- Compare: move the "Judge each day by its" basis toggle out of the filter sheet into
the inline comfort card above the results (a scoring control, like the comfort
slider). Handler is id-based, so no JS change for the move.
- Metric selector is duplicated, not relocated: revert the sheetOnly relocation in
filtersheet.js; keep the inline selector visible on all viewports and add a synced
copy inside each page's filter sheet (mobile-only via CSS). The sheet copy clones the
inline buttons; a single setter (setDistMetric / setColorMetric) drives the shared
state and reflects the active metric on both, so picking any of the 8 metrics in
either selector syncs the other and re-renders. Applies to compare's "Distribution
by" and calendar's "Color the calendar by".
Frontend-only; no backend or payload change.
- Season filter: add a "Full year" select-all row above the four seasons (checked at
12 months, clears to none, indeterminate when partial). One shared change in
seasonFilterDropdown/applySeasonMonthChange/syncSeasonChecks covers both pages; the
summary already reads "All year" at 12.
- Metric selector rides the filter sheet on phones: initFilterSheet gains a sheetOnly
option that relocates given controls into the sheet at the 640px breakpoint and
restores them inline on desktop (matchMedia; reparenting keeps listeners). Compare
passes its "Distribution by" control, calendar its "Color the calendar by" block.
- Compare comfort/tolerance slider moved out of the params panel into a standalone
full-width card above the results, so it's always visible instead of buried in the
mobile pill sheet. The params sheet now holds basis + season + date range.
Frontend-only; no backend or payload change.
Compare gains a time-of-year filter it never had; the calendar's flat 4-season
filter is upgraded to the same model so both pages filter time identically.
- Shared season/month model in shared.js: seasons are the primary, color-coded
selector, the 12 months a nested suboption, backed by one Set of month indices.
seasonFilterDropdown/syncSeasonChecks/applySeasonMonthChange/seasonSummaryText
plus month<->bitmask helpers, reused by both pages.
- Compare: filter gates r.date's month into computeStats and the distribution;
instant re-rank, no refetch. Persisted (cmpMonths bitmask) and carried in the
URL hash (m=, omitted when all 12). Empty-selection hint when a filter excludes
every day.
- Calendar: checkedSeasons -> checkedMonths, applied in the render loop; persisted
as calMonths. Season checkbox is checked/indeterminate by how many of its months
are on.
- Mobile filter sheet (filtersheet.js): a subtle floating pill slides the page's
filter panel up as a bottom sheet, reachable from anywhere on the page, on both
compare and calendar. Desktop keeps the inline panel unchanged. Respects
reduced-motion and the home-indicator inset.
Frontend-only; no backend or payload change.