CSS: delete dead selectors, one mobile block, shared control recipes (#50)

- Deleted the rules for elements that no longer exist (verified by
  auditing every style.css class selector against all class usage in
  HTML/JS, including dynamically-built names): the pre-modal inline
  search/suggestions, the old two-column .layout + inline #map, the
  .panel fixed-height scroller (+ its now-pointless .panel-full
  neutralizer and 900px escape), .share-btn, the pre-dropdown calendar
  filter chips, .series-toggle, the .grade.danger/.d-rec-* set and the
  bare .legend block. Leaflet's classes stay (styled runtime DOM).
- The four scattered max-width:640px blocks are now one block at the end
  of the sheet, where mobile overrides belong.
- The accent-button recipe (5 copies) and the 16px text-input recipe
  (4 copies) are each one grouped rule; components keep only their
  deltas. The iOS zoom-on-focus rule now has a single documented home.
  (The consolidation also restored the .date-row button rule that the
  dead-search deletion would otherwise have taken with it.)

993 -> 919 lines. Verified pixel-identical: full-page screenshots of all
five pages at 390/800/1280px and the opened picker modal are
byte-for-byte equal before/after (headless Chromium).
This commit is contained in:
Emi Griffith 2026-07-11 13:42:41 -07:00 committed by GitHub
parent 591f5ec495
commit b7bad50e96

View file

@ -99,32 +99,23 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
}
.controls { margin-bottom: 18px; display: flex; flex-wrap: wrap; gap: 16px; align-items: flex-start; }
.search { position: relative; flex: 1 1 340px; display: flex; gap: 8px; }
.search input {
flex: 1; min-width: 0; padding: 11px 14px; border-radius: 10px;
border: 1px solid var(--border); background: var(--surface); color: var(--text);
font-size: 16px; /* >=16px keeps iOS Safari from zooming on focus */
/* ---- shared control recipes ----
One home for the accent-button and text-input look every view reuses. The
16px input font is load-bearing (below it iOS zooms on focus); buttons keep
their 44px touch targets in the per-component rules, which carry only each
control's differences from these. */
.date-row button, .range-refresh, .find-btn, .mp-search button, .mp-confirm {
border-radius: 10px; border: none; cursor: pointer;
background: var(--accent); color: #1a1206; font-weight: 600;
}
.search button, .date-row button {
padding: 11px 18px; border-radius: 10px; border: none;
background: var(--accent); color: #1a1206; font-weight: 600; cursor: pointer;
}
.suggestions {
position: absolute; top: 52px; left: 0; right: 78px; z-index: 500;
list-style: none; margin: 0; padding: 4px;
background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
box-shadow: 0 12px 30px rgba(0,0,0,.35);
}
.suggestions li { padding: 9px 12px; border-radius: 7px; cursor: pointer; font-size: 14px; }
.suggestions li:hover { background: var(--surface-2); }
.suggestions .sub { color: var(--muted); font-size: 12px; }
.date-row { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.date-row label { font-size: 13px; color: var(--muted); display: flex; flex-direction: column; gap: 4px; }
.date-row input {
.date-row input, .cal-range input, .day-date input, .mp-search input {
padding: 9px 12px; border-radius: 10px; border: 1px solid var(--border);
background: var(--surface); color: var(--text); font-size: 16px;
}
.date-row button { padding: 11px 18px; }
.date-row { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.date-row label { font-size: 13px; color: var(--muted); display: flex; flex-direction: column; gap: 4px; }
/* "Today" quick-reset chip beside the target date. Outlined when the target is a
past date (a clickable "jump to today"); filled accent while already on today. */
.date-row .today-chip {
@ -140,20 +131,10 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
.hint { color: var(--muted); font-size: 12.5px; max-width: 220px; }
.layout { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
@media (max-width: 900px) { .layout { grid-template-columns: 1fr; } }
#map {
height: 560px; border-radius: 14px; border: 1px solid var(--border);
z-index: 1;
}
.panel {
height: 560px; overflow-y: auto;
background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
padding: 20px;
}
@media (max-width: 900px) { .panel { height: auto; } }
.placeholder p { color: var(--text); }
.muted { color: var(--muted); font-size: 13.5px; }
@ -166,7 +147,7 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
.loc-meta { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.loc-meta li { color: var(--muted); font-size: 12.5px; line-height: 1.35; }
.share { display: flex; gap: 6px; flex-shrink: 0; flex-wrap: wrap; }
.share button, .share .share-btn {
.share button {
padding: 6px 11px; border-radius: 8px; border: 1px solid var(--border);
background: var(--surface-2); color: var(--text); font-size: 12px; cursor: pointer;
white-space: nowrap; text-decoration: none; display: inline-flex; align-items: center; gap: 5px;
@ -176,7 +157,7 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
.ic { width: 1em; height: 1em; vertical-align: -0.14em; flex-shrink: 0; }
.ic-lg { width: 26px; height: 26px; }
.wx { width: 1.15em; height: 1.15em; vertical-align: -0.2em; }
.share button:hover, .share .share-btn:hover { border-color: var(--accent); }
.share button:hover { border-color: var(--accent); }
/* Call-to-action into the 2-year calendar a compact button-sized link, so the
graded results stay the page's focal point. */
@ -346,18 +327,14 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
.cal-range label {
display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--muted);
}
.cal-range input {
width: 100%; font-size: 16px; padding: 8px 10px; border-radius: 8px; min-height: 40px;
border: 1px solid var(--border); background: var(--surface); color: var(--text);
}
.cal-range input { width: 100%; padding: 8px 10px; border-radius: 8px; min-height: 40px; }
.cal-range .hint { margin: 0; flex: 0 0 auto; max-width: none; font-size: 12px; color: var(--muted); }
/* Appears under the pickers once the user edits a date; no request is made until
it's tapped. Spans both columns so it reads as a clear confirm step. */
.range-refresh {
grid-column: 1 / -1; margin-top: 2px;
padding: 10px 16px; min-height: 44px; border-radius: 9px; cursor: pointer;
font-size: 15px; font-weight: 700;
background: var(--accent); color: #1a1206; border: 1px solid var(--accent);
padding: 10px 16px; min-height: 44px; border-radius: 9px;
font-size: 15px; font-weight: 700; border: 1px solid var(--accent);
}
.range-refresh:hover { filter: brightness(1.05); }
@ -389,21 +366,10 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
.cal-seasonyear .cal-weather { grid-column: auto; }
.cal-seasonyear .cal-weather .cal-dd-panel { left: auto; right: 0; min-width: 420px; }
}
.cal-filter-group { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.cal-filter-label {
font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
color: var(--muted); font-weight: 700; margin-right: 2px;
}
.cal-chip {
display: inline-flex; align-items: center; gap: 7px; cursor: pointer; user-select: none;
font-size: 13px; padding: 6px 11px; min-height: 36px;
border: 1px solid var(--border); border-radius: 9px; background: var(--surface);
}
.cal-chip input { accent-color: var(--accent); width: 16px; height: 16px; margin: 0; }
.cal-chip:has(input:checked) {
border-color: var(--accent);
background: color-mix(in oklab, var(--accent), transparent 88%);
}
.cal-head { margin-bottom: 16px; }
.cal-head h2 { margin: 0 0 2px; font-size: 18px; }
@ -484,10 +450,6 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
.day-weather { margin: 2px 0 4px; font-size: 16px; font-weight: 800; }
.day-nav { display: flex; align-items: flex-end; gap: 8px; }
.day-date { font-size: 13px; color: var(--muted); display: flex; flex-direction: column; gap: 4px; }
.day-date input {
padding: 9px 12px; border-radius: 10px; border: 1px solid var(--border);
background: var(--surface); color: var(--text); font-size: 16px;
}
.day-step {
min-width: 44px; min-height: 44px; padding: 0 12px; border-radius: 10px;
border: 1px solid var(--border); background: var(--surface-2); color: var(--text);
@ -546,33 +508,6 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
.ladder-mk { justify-self: start; min-width: 0; }
.ladder-mark { color: var(--accent); font-weight: 800; white-space: nowrap; font-size: 12.5px; }
@media (max-width: 640px) {
.calendar { gap: 16px; }
.metric-toggle { width: 100%; }
/* 7 metrics wrap to ~4 per row on a phone instead of overflowing one line. */
.metric-toggle button { flex: 1 0 25%; padding: 11px 4px; font-size: 12px; }
/* Compress the day tooltip so it fits narrow phone screens without cutting off. */
#cal-tip { padding: 7px 9px; min-width: 0; font-size: 11.5px; line-height: 1.4; }
#cal-tip .tt-type { font-size: 13.5px; margin: 1px 0 5px; padding-bottom: 5px; }
#cal-tip .tt-grid { column-gap: 8px; row-gap: 2px; }
/* Day ladder on mobile: tighten the fixed tracks but keep every column (including
the percentile range) so the ranges still line up down the ladder. */
.day-nav { width: 100%; }
.day-date { flex: 1; }
.ladder-row { grid-template-columns: 13px 90px 54px 1fr 48px; column-gap: 8px; font-size: 12.5px; }
}
/* Recent | Forecast time-range switch above the trend chart. */
.series-toggle {
display: inline-flex; border: 1px solid var(--border); border-radius: 10px;
overflow: hidden; margin-bottom: 14px;
}
.series-toggle button {
padding: 8px 22px; background: var(--surface); color: var(--text); border: none;
cursor: pointer; font-size: 13.5px; font-weight: 600; min-height: 40px;
}
.series-toggle button + button { border-left: 1px solid var(--border); }
.series-toggle button.active { background: var(--accent); color: #1a1206; }
/* Compact "graded days" table: a ROW per metric, a COLUMN per day. Wide runs
scroll horizontally in their own container; the metric-label column is pinned. */
@ -638,81 +573,21 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
.g-wet-9 { color: var(--wet-9); } .m-wet-9 { background: var(--wet-9); }
/* "Near Record" danger tiers: fill the whole grade cell to make it pop. */
.grade.danger { border-color: transparent; }
.grade.danger .lbl, .grade.danger .val, .grade.danger .band { color: #fff; }
.grade.danger .meter { background: rgba(255,255,255,.28); }
.grade.d-rec-hot { background: var(--rec-hot); }
.grade.d-rec-cold { background: var(--rec-cold); }
.error { color: #e06a6a; font-size: 14px; }
.spinner { color: var(--muted); font-size: 14px; }
.legend { margin-top: 18px; font-size: 12px; color: var(--muted); }
.legend b { color: var(--text); font-weight: 600; }
/* --- phones / narrow screens --- */
@media (max-width: 640px) {
header { padding: 14px 16px; }
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. */
.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; }
main { padding: 14px 14px 40px; }
.controls { gap: 12px; margin-bottom: 14px; }
/* Map + panel stack (from the 900px rule); shrink the map so results are
reachable with less scrolling on a phone. */
#map { height: 44vh; min-height: 240px; }
.panel { padding: 16px; }
/* Give buttons a comfortable touch target (~44px). */
.search button, .date-row button { padding: 12px 16px; min-height: 44px; }
.share button { padding: 9px 12px; font-size: 12.5px; min-height: 38px; }
.date-row { gap: 10px; width: 100%; }
.hint { max-width: none; flex-basis: 100%; }
.loc-head { flex-wrap: wrap; }
.share { flex-wrap: wrap; }
/* Keep the normal cards legible when very narrow. */
.normals { gap: 8px; }
.normal-card { padding: 10px 11px; }
.normal-card .big { font-size: 19px; }
/* Compact table + series toggle tuned for phone width. */
.series-toggle { width: 100%; }
.series-toggle button { flex: 1; }
/* Chart metric toggle: force an even 4-per-row grid so the buttons line up
(without this the flex-wrap sizes each to its label and the rows go ragged). */
.chart-toggle { width: 100%; }
.chart-toggle button { flex: 1 0 25%; padding: 9px 4px; font-size: 12px; }
.rd-c { min-height: 30px; font-size: 11px; border-radius: 5px; }
.rd-mlabel { font-size: 10px; padding-right: 4px; }
.rd-colh { font-size: 9px; }
.rd-colh b { font-size: 10.5px; }
}
/* --- Find button + current-place label (opens the modal map picker) --- */
.find-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; flex: 1 1 340px; }
.find-btn {
display: inline-flex; align-items: center; gap: 8px;
padding: 11px 18px; border-radius: 10px; border: none; cursor: pointer;
background: var(--accent); color: #1a1206; font-weight: 700; font-size: 15px; min-height: 44px;
padding: 11px 18px; font-weight: 700; font-size: 15px; min-height: 44px;
}
.find-btn svg { width: 18px; height: 18px; flex-shrink: 0; }
.find-btn:hover { filter: brightness(1.05); }
.loc-label { color: var(--text); font-weight: 600; font-size: 14px; }
/* Weekly panel is now full width (the map lives in the picker, not inline). */
.panel-full { height: auto; overflow: visible; }
/* Link styling for the compact legend notes + guide page. */
.tk-note a, .hint a, .guide-back a { color: var(--accent); text-decoration: none; font-weight: 600; }
@ -742,14 +617,8 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
}
.mp-close:hover { color: var(--text); }
.mp-search { position: relative; display: flex; gap: 8px; padding: 12px 16px 8px; }
.mp-search input {
flex: 1; min-width: 0; padding: 11px 14px; border-radius: 10px;
border: 1px solid var(--border); background: var(--bg); color: var(--text); font-size: 16px;
}
.mp-search button {
padding: 11px 16px; border-radius: 10px; border: none; min-height: 44px; cursor: pointer;
background: var(--accent); color: #1a1206; font-weight: 600;
}
.mp-search input { flex: 1; min-width: 0; padding: 11px 14px; background: var(--bg); }
.mp-search button { padding: 11px 16px; min-height: 44px; }
.mp-sug {
position: absolute; top: 100%; left: 16px; right: 16px; z-index: 5;
list-style: none; margin: 4px 0 0; padding: 4px; max-height: 240px; overflow-y: auto;
@ -791,10 +660,7 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
padding: 12px 16px 16px; flex-wrap: wrap;
}
.mp-hint { color: var(--muted); font-size: 12.5px; flex: 1 1 auto; min-width: 0; }
.mp-confirm {
padding: 11px 18px; border-radius: 10px; border: none; min-height: 44px; cursor: pointer;
background: var(--accent); color: #1a1206; font-weight: 700;
}
.mp-confirm { padding: 11px 18px; min-height: 44px; font-weight: 700; }
.mp-confirm:disabled { opacity: .45; cursor: default; }
/* --- calendar Season/Year filters as compact dropdowns (native <details>) --- */
@ -899,13 +765,6 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
.guide-metrics dd { margin: 0; color: var(--muted); font-size: 14px; }
.guide-back { margin-top: 8px; }
@media (max-width: 640px) {
.mp-overlay { padding: 0; }
.mp-modal { max-width: none; max-height: 100vh; height: 100vh; border-radius: 0; border: none; }
.find-bar { width: 100%; }
.guide-metrics { grid-template-columns: 1fr; gap: 2px 0; }
.guide-metrics dt { margin-top: 10px; }
}
/* ===== Compare view ===== */
.cmp-locs { flex: 1 1 340px; }
@ -986,7 +845,74 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
.cmp-mad { margin: 12px 0 0; font-size: 13px; color: var(--muted); }
.cmp-mad b { color: var(--text); }
/* --- phones / narrow screens every mobile override lives in this one
block (they used to be scattered across four) --- */
@media (max-width: 640px) {
.calendar { gap: 16px; }
.metric-toggle { width: 100%; }
/* 7 metrics wrap to ~4 per row on a phone instead of overflowing one line. */
.metric-toggle button { flex: 1 0 25%; padding: 11px 4px; font-size: 12px; }
/* Compress the day tooltip so it fits narrow phone screens without cutting off. */
#cal-tip { padding: 7px 9px; min-width: 0; font-size: 11.5px; line-height: 1.4; }
#cal-tip .tt-type { font-size: 13.5px; margin: 1px 0 5px; padding-bottom: 5px; }
#cal-tip .tt-grid { column-gap: 8px; row-gap: 2px; }
/* Day ladder on mobile: tighten the fixed tracks but keep every column (including
the percentile range) so the ranges still line up down the ladder. */
.day-nav { width: 100%; }
.day-date { flex: 1; }
.ladder-row { grid-template-columns: 13px 90px 54px 1fr 48px; column-gap: 8px; font-size: 12.5px; }
header { padding: 14px 16px; }
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. */
.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; }
main { padding: 14px 14px 40px; }
.controls { gap: 12px; margin-bottom: 14px; }
/* Map + panel stack (from the 900px rule); shrink the map so results are
reachable with less scrolling on a phone. */
.panel { padding: 16px; }
/* Give buttons a comfortable touch target (~44px). */
.date-row button { padding: 12px 16px; min-height: 44px; }
.share button { padding: 9px 12px; font-size: 12.5px; min-height: 38px; }
.date-row { gap: 10px; width: 100%; }
.hint { max-width: none; flex-basis: 100%; }
.loc-head { flex-wrap: wrap; }
.share { flex-wrap: wrap; }
/* Keep the normal cards legible when very narrow. */
.normals { gap: 8px; }
.normal-card { padding: 10px 11px; }
.normal-card .big { font-size: 19px; }
/* Compact table tuned for phone width. */
/* Chart metric toggle: force an even 4-per-row grid so the buttons line up
(without this the flex-wrap sizes each to its label and the rows go ragged). */
.chart-toggle { width: 100%; }
.chart-toggle button { flex: 1 0 25%; padding: 9px 4px; font-size: 12px; }
.rd-c { min-height: 30px; font-size: 11px; border-radius: 5px; }
.rd-mlabel { font-size: 10px; padding-right: 4px; }
.rd-colh { font-size: 9px; }
.rd-colh b { font-size: 10.5px; }
.mp-overlay { padding: 0; }
.mp-modal { max-width: none; max-height: 100vh; height: 100vh; border-radius: 0; border: none; }
.find-bar { width: 100%; }
.guide-metrics { grid-template-columns: 1fr; gap: 2px 0; }
.guide-metrics dt { margin-top: 10px; }
.cmp-params { grid-template-columns: 1fr; padding: 14px; }
.cmp-basis-block .metric-toggle button { flex: 1 0 22%; padding: 10px 4px; }
.cmp-big b { font-size: 20px; }