/* Weather — styles.
   Every size is in rem, so the in-app text size setting (--scale on <html>) and Chrome's own zoom
   both scale the whole app. Every color comes from the theme variables below; each color pair
   meets WCAG AAA contrast (7:1 or better). */

/* Atkinson Hyperlegible Next, hosted with the app so it also works offline (license: fonts/OFL.txt).
   Each file is a variable font that covers both weights the app uses, bold (700) and extra-bold (800). */
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  font-style: normal;
  font-weight: 700 800;
  font-display: swap;
  src: url("../fonts/atkinson-hyperlegible-next-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  font-style: normal;
  font-weight: 700 800;
  font-display: swap;
  src: url("../fonts/atkinson-hyperlegible-next-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --scale: 1;
  font-size: calc(125% * var(--scale));

  --bg: #000000;
  --fg: #FFFFFF;
  --temp: #FFFFFF;
  --rain: #FFFFFF;
  --accent: #FFFFFF;
  --on-accent: #000000;

  /* The page's own text color. Color-test swatches restyle themselves but keep this for their frames. */
  --frame: var(--fg);
}

/* --- Themes: data-bg is the Background setting, data-palette is the color set (or "none"). --- */

[data-bg="dark"]  { --bg: #000000; --fg: #FFFFFF; --temp: #FFFFFF; --rain: #FFFFFF; --accent: #FFFFFF; --on-accent: #000000; }
[data-bg="light"] { --bg: #FFFFFF; --fg: #000000; --temp: #000000; --rain: #000000; --accent: #000000; --on-accent: #FFFFFF; }

/* Cool: lavender temperature, cyan rain */
[data-bg="dark"][data-palette="cool"]  { --temp: #C4B5FD; --rain: #00FFFF; --accent: #00FFFF; --on-accent: #000000; }
[data-bg="light"][data-palette="cool"] { --temp: #3B1F8F; --rain: #004466; --accent: #004466; --on-accent: #FFFFFF; }

/* Aqua: cyan text on black, navy text on white */
[data-bg="dark"][data-palette="aqua"]  { --fg: #00FFFF; --temp: #00FFFF; --rain: #FFFFFF; --accent: #00FFFF; --on-accent: #000000; }
[data-bg="light"][data-palette="aqua"] { --fg: #00264D; --temp: #00264D; --rain: #004466; --accent: #00264D; --on-accent: #FFFFFF; }

/* Yellow: yellow on black, black on cream */
[data-bg="dark"][data-palette="yellow"]  { --fg: #FFFF00; --temp: #FFFF00; --rain: #00FFFF; --accent: #FFFF00; --on-accent: #000000; }
[data-bg="light"][data-palette="yellow"] { --bg: #FFFFC8; --fg: #000000; --temp: #000000; --rain: #004466; --accent: #000000; --on-accent: #FFFFC8; }

/* --- Base --- */

*, *::before, *::after { box-sizing: border-box; }

html {
  background: var(--bg);
  color: var(--fg);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--fg);
  font-family: "Atkinson Hyperlegible Next", "Atkinson Hyperlegible", Verdana, Arial, sans-serif;
  font-weight: 700;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}

h1, h2, h3, p, ul, ol { margin: 0; font-size: inherit; font-weight: inherit; }

button {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: inherit;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

svg { display: block; flex: none; }

[hidden] { display: none !important; }

/* Words for screen readers and voice control only, such as "high" and "low" beside the numbers.
   Keep them inside a positioned element, or hidden words in off-screen days widen the page. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

:focus { outline: none; }
:focus-visible { outline: 0.3rem solid var(--frame); outline-offset: 0.25rem; }

.view {
  max-width: 120rem;
  margin: 0 auto;
  padding: 1rem 1.5rem 3rem;
}

/* --- Things you can click to hear --- */

.readable, .hearable { border-radius: 0.5rem; cursor: default; }
.tap-read .readable, .tap-read .hearable { cursor: pointer; }
.readable.is-reading, .hearable.is-reading { outline: 0.45rem solid var(--frame); outline-offset: 0.15rem; }

/* --- Shared buttons --- */

.arrow-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 4.25rem;
  min-height: 4.25rem;
  border-radius: 0.6rem;
  background: var(--accent);
  color: var(--on-accent);
}
.arrow-btn svg { width: 2.75rem; height: 2.75rem; }
.arrow-btn polygon { fill: currentColor; stroke: currentColor; stroke-width: 1.5; stroke-linejoin: round; }

/* At the first or last day the arrow turns hollow: still high contrast, clearly "nothing more this way". */
.arrow-btn[aria-disabled="true"] {
  background: transparent;
  color: var(--fg);
  box-shadow: inset 0 0 0 0.2rem var(--fg);
  cursor: default;
}
.arrow-btn[aria-disabled="true"] polygon { fill: none; }

.action-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  min-height: 4rem;
  padding: 0.8rem 1.5rem;
  border-radius: 0.6rem;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 1.6rem;
  line-height: 1.1;
  text-align: center;
}
.action-btn svg { width: 2.4rem; height: 2.4rem; }

/* A button that can't be used right now (Move up on the first place): hollow, like an end arrow. */
.action-btn[aria-disabled="true"] {
  background: transparent;
  color: var(--fg);
  box-shadow: inset 0 0 0 0.2rem var(--fg);
  cursor: default;
}

/* A thick outline shows what the mouse is over (mouse and trackpad only, not touch). */
@media (hover: hover) {
  .arrow-btn:not([aria-disabled="true"]):hover,
  .action-btn:not([aria-disabled="true"]):hover,
  .choice:hover,
  .result-btn:hover,
  .hold-btn:hover,
  .swatch:hover {
    outline: 0.25rem solid var(--frame);
    outline-offset: 0.2rem;
  }
  .tap-read .readable:not(.is-reading):hover,
  .tap-read .hearable:not(.is-reading):hover {
    outline: 0.2rem solid var(--frame);
    outline-offset: 0.15rem;
  }
}

/* --- Place bar --- */

.place-bar {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 1rem;
  padding-bottom: 1rem;
}
/* With one place there's nothing to switch to, so the arrows go and the name gets the whole width. */
.single-place .place-bar { grid-template-columns: minmax(0, 1fr); }
.single-place .place-bar .arrow-btn { display: none; }

.place-title { text-align: center; }

.place-name {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  padding: 0.25rem 0.5rem;
  text-align: center;
}
.place-name-text { font-size: 2.4rem; line-height: 1.1; overflow-wrap: break-word; }
.place-count { margin-top: 0.25rem; font-size: 1.1rem; }
.place-count:empty { display: none; }

/* --- Severe weather alerts: inverted, with a warning sign, so they stand out without color. ---
   No motion and no sound; a click reads the warning. Empty (and takes no space) when there are none. */

.alerts { display: flex; flex-direction: column; gap: 0.75rem; margin-bottom: 1rem; }
.alerts:empty { margin: 0; }

.alert {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  width: 100%;
  padding: 0.9rem 1.2rem;
  border-radius: 0.6rem;
  background: var(--accent);
  color: var(--on-accent);
  text-align: left;
}
.alert-icon { width: 3.2rem; height: 3.2rem; }
.alert-text { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.alert-event { font-size: 2.1rem; font-weight: 800; line-height: 1.15; overflow-wrap: break-word; }
.alert-until { font-size: 1.5rem; line-height: 1.2; }

/* --- Notice: getting the weather, an old forecast, or no connection. Hidden when all is well. --- */

.notice {
  display: block;
  width: 100%;
  margin-bottom: 1rem;
  padding: 0.8rem 1.1rem;
  border: 0.25rem solid var(--fg);
  border-radius: 0.6rem;
  font-size: 1.6rem;
  line-height: 1.3;
  text-align: left;
}

/* No forecast yet: the town, the notice and Read aloud only. */
.no-forecast .now-temp,
.no-forecast .now-hilo,
.no-forecast .now-rain,
.no-forecast .chart-group { display: none; }

/* --- Right now --- */

.now {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 2.5rem;
  padding: 1.25rem 0;
  border-top: 0.25rem solid var(--fg);
}

.now-temp {
  padding: 0 0.25rem;
  /* Huge, but never wider than the screen: room for four characters such as "−10°" on a phone. */
  font-size: min(7rem, calc((100vw - 2.5rem) / 2.5));
  font-weight: 800;
  line-height: 0.95;
  letter-spacing: -0.02em;
}

.now-hilo {
  display: flex;
  flex-direction: column;
  padding: 0.25rem 0.5rem;
  font-size: 2.5rem;
  line-height: 1.15;
}

.now-rain { display: flex; flex-direction: column; padding: 0.25rem 0.5rem; }
.now-rain-label { font-size: 1.3rem; }
.now-rain-value { font-size: 2.5rem; line-height: 1.1; color: var(--rain); }

.read-btn { margin-left: auto; min-width: 14rem; font-size: 1.7rem; }

/* --- Charts --- */

/* A section: the 7-day chart, then the hour-by-hour graph for the selected day. */
.chart-group {
  padding: 1rem 0 0.75rem;
  border-top: 0.25rem solid var(--fg);
}

.chart-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
  margin-bottom: 0.5rem;
}
.chart-title { font-size: 1.7rem; }
.day-range { padding: 0.2rem 0.4rem; font-size: 1.3rem; }

.chart-body {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: stretch;
  gap: 0.75rem;
}

.track {
  --visible: 3;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc(100% / var(--visible));
  overflow: hidden;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
  cursor: grab;
}
.track.dragging, .track.dragging * { cursor: grabbing !important; }

.day {
  position: relative; /* keeps its visually hidden words inside it, so off-screen days can't widen the page */
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
  padding: 0.4rem 0;
  cursor: grab;
}
.tap-read .track .day { cursor: pointer; }

/* The chart clips its edges, so outlines on days are drawn inside the day. */
.track .day.is-reading { outline-offset: -0.45rem; }
@media (hover: hover) {
  .tap-read .track .day:not(.is-reading):hover { outline-offset: -0.2rem; }
}

.day-name { font-size: 1.5rem; white-space: nowrap; }

.temp-day .day-name { margin-bottom: 0.4rem; }
.temp-gap { flex: none; }
.temp-num { font-size: 2.3rem; font-weight: 800; line-height: 1.1; }
.temp-bar {
  flex: none;
  width: 1.75rem;
  margin: 0.3rem 0;
  border-radius: 0.5rem;
  background: var(--temp);
}

.rain-plot {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  width: 100%;
  height: calc(var(--rain-plot, 5.5rem) + 3rem);
}
.rain-num { margin-bottom: 0.3rem; font-size: 2.3rem; font-weight: 800; line-height: 1.1; }
.rain-bar { flex: none; width: 55%; max-width: 5.5rem; background: var(--rain); }
/* Days sit edge to edge, so each day's piece of baseline joins into one line. */
.rain-base { align-self: stretch; height: 0.3rem; background: var(--fg); }
.rain-day .day-name { margin-top: 0.4rem; }

/* The selected day's name is inverted, matching the day pill on the hour-by-hour graph below it. */
.day[aria-pressed="true"] .day-name,
.day-pill {
  padding: 0 0.5rem;
  border-radius: 0.4rem;
  background: var(--accent);
  color: var(--on-accent);
}

/* --- Hour-by-hour graphs --- */

.hourly {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 0.15rem solid var(--fg);
}

.hourly-title {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem 0.8rem;
  padding: 0.15rem 0.3rem;
}

.hg {
  --hg-label-gap: 0.8rem; /* space after each block's numbers; js/hourly.js uses it to pick the block size */
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: 0.3rem;
  padding: 0.75rem 0 0.25rem;
}

/* The temperature legend, at the top of the graph: "Temp" (solid line, filled dot) and "Feels like"
   (dashed line, hollow dot). It wraps onto two lines on narrow screens. */
.hg-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.75rem;
  padding: 0.6rem 0.6rem 0;
  font-size: 1.3rem;
  line-height: 1.2;
}
.hg-legend-item { display: inline-flex; align-items: center; gap: 0.6rem; }
.hg-legend-sample { position: relative; flex: none; width: 3.5rem; height: 1.3rem; }
.hg-legend-sample .hg-sample { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.hg-legend-sample .hg-dot { left: 50%; top: 50%; }

/* A saved forecast from before hourly numbers were added: says so until the next update. */
.hg-empty { max-width: 40em; padding: 1rem 0.6rem; font-size: 1.4rem; line-height: 1.4; }

/* The side padding leaves room for the last block's numbers. */
.hg-cell { grid-column: 1; min-width: 0; padding-inline: 0.6rem; }
.hg-inner { position: relative; height: 100%; }

/* --hg-plot-h is the graph's height above the baseline. Hour targets stop at it; block highlights start under it. */
.hg-temp { --hg-plot-h: 7rem; }
.hg-rain { --hg-plot-h: 5rem; }
.hg-plot { height: var(--hg-plot-h); }
.hg-plot-rain { border-bottom: 0.3rem solid var(--fg); }

.hg-hours { height: 1.8rem; font-size: 1.3rem; }
.hg-values { height: 2.5rem; font-size: 2rem; font-weight: 800; }
.hg-feels { font-size: 1.7rem; font-weight: 700; }

/* Each block's first hour and its numbers, written at the left edge of the block. */
.hg-tick {
  position: absolute;
  top: 0;
  padding-left: 0.4rem;
  line-height: 1.2;
  white-space: nowrap;
}

.hg-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }

/* Lines keep the same thickness and dash length however the graph is stretched. */
.line-temp,
.line-feels {
  fill: none;
  vector-effect: non-scaling-stroke;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.line-temp { stroke: var(--temp); stroke-width: 0.4rem; }
.line-feels { stroke: var(--fg); stroke-width: 0.3rem; stroke-dasharray: 0.7rem 0.55rem; }

.hg-dot {
  position: absolute;
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 50%;
  transform: translate(-50%, -50%);
}
.hg-dot-temp { background: var(--temp); }
.hg-dot-feels { background: var(--bg); border: 0.25rem solid var(--fg); }

.hg-bars { position: absolute; inset: 0; display: flex; align-items: flex-end; }
.hg-slot { flex: 1; display: flex; align-items: flex-end; justify-content: center; height: 100%; }
.hg-bar { width: 70%; background: var(--rain); }

.hg-now {
  position: absolute;
  top: -0.25rem;
  bottom: 0;
  width: 0.25rem;
  margin-left: -0.125rem;
  background: var(--fg);
}
.hg-now-label {
  position: absolute;
  top: 0;
  left: 0.45rem;
  padding: 0 0.35rem;
  border-radius: 0.3rem;
  background: var(--fg);
  color: var(--bg);
  font-size: 1rem;
  line-height: 1.3;
  white-space: nowrap;
}
.hg-now-left .hg-now-label { left: auto; right: 0.45rem; }

/* Below the baseline: thin dividers between time blocks, and a thick box around the chosen block. */
.hg-blocks-cell { pointer-events: none; }
.hg-divider {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 0.15rem;
  margin-left: -0.075rem;
  background: var(--fg);
}

/* Click targets over the graph: one per hour above the baseline, one per time block below it. */
.hg-hits-cell { z-index: 1; }
.hg-hit {
  position: absolute;
  top: 0;
  bottom: 0;
  border-radius: 0.5rem;
}

/* Every hour: its bar or point, above the baseline only. Clicking one also chooses its block, so hours
   are always clickable. Pointing gives a thin outline; reading it aloud, a thick one of the same size. */
.hg-hour-hit { bottom: auto; height: var(--hg-plot-h); cursor: pointer; }

/* Every time block: below the baseline only. The chosen block has a thick line around it; pointing at
   any other block draws a thin line around exactly the same box. */
.hg-block-hit {
  top: calc(var(--hg-plot-h) + 0.1rem);
  bottom: -0.2rem;
  border: 0 solid var(--frame);
}
.hg-chosen { border-width: 0.35rem; }
.tap-read .hg-chosen { cursor: pointer; } /* clicking it reads the block */
.hg-block { cursor: pointer; }
.hg-block:focus-visible { outline: none; border-width: 0.2rem; }
@media (hover: hover) {
  .hg-hour-hit:not(.is-reading):hover { outline: 0.2rem solid var(--frame); outline-offset: 0.15rem; }
  .hg-block:hover { border-width: 0.2rem; }
}


/* --- Settings button: far from everything else, and it needs a press and hold --- */

.settings-zone {
  display: flex;
  justify-content: center;
  margin-top: 5rem;
  padding-top: 1.5rem;
  border-top: 0.25rem solid var(--fg);
}

.hold-btn {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  padding: 1rem 2.5rem 1.5rem;
  border: 0.25rem solid var(--fg);
  border-radius: 0.75rem;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
}
.hold-label { display: flex; align-items: center; gap: 0.6rem; font-size: 1.6rem; }
.hold-label svg { width: 2.2rem; height: 2.2rem; }
.hold-hint { font-size: 1.15rem; }

/* Fills left to right while held. --hold-ms is set from js/app.js so the bar and the timer agree. */
.hold-fill {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 0.6rem;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.15s ease-out;
}
.hold-btn.holding .hold-fill {
  transform: scaleX(1);
  transition: transform var(--hold-ms, 2s) linear;
}

/* --- Settings and color screens --- */

.panel-top {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 0;
  background: var(--bg);
  border-bottom: 0.25rem solid var(--fg);
}
.panel-top h1 { font-size: 2.4rem; }

.panel-bottom { display: flex; justify-content: center; padding-top: 2rem; }

.setting { padding: 1.5rem 0; border-bottom: 0.15rem solid var(--fg); }
.setting-title { margin-bottom: 0.6rem; font-size: 1.7rem; }
.setting-title .readable { padding: 0.15rem 0.3rem; }
.setting-note { max-width: 40em; margin-bottom: 0.9rem; font-size: 1.2rem; line-height: 1.4; }

.choices, .stepper { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem 1rem; }

.choice {
  min-width: 9rem;
  min-height: 4rem;
  padding: 0.7rem 1.4rem;
  border: 0.25rem solid var(--fg);
  border-radius: 0.6rem;
  font-size: 1.5rem;
  text-align: center;
}
.choice[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
/* The check mark means "chosen" without relying on color. */
.choice[aria-pressed="true"]::before { content: "\2713\00A0" / ""; }

.step-value { min-width: 9rem; font-size: 1.6rem; text-align: center; }

.size-sample { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem 2rem; margin-top: 1rem; }
/* Same size as the temperature on the main screen, including its cap on narrow screens. */
.size-sample-big { font-size: min(7rem, calc((100vw - 2.5rem) / 2.5)); font-weight: 800; line-height: 0.95; }
.size-sample-mid { font-size: 2.5rem; }

.places-list { margin-bottom: 1rem; padding: 0; list-style: none; }

.place-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.5rem;
  padding: 1rem 0;
  border-bottom: 0.15rem solid var(--fg);
}
.place-row:first-child { border-top: 0.15rem solid var(--fg); }
.place-row-name { min-width: 12rem; padding: 0.15rem 0.3rem; font-size: 1.9rem; overflow-wrap: break-word; }
.place-actions { display: flex; flex-wrap: wrap; gap: 0.75rem; }
.place-actions .action-btn { min-height: 3.5rem; padding: 0.6rem 1.1rem; font-size: 1.4rem; }

.place-status { margin-bottom: 1rem; font-size: 1.5rem; line-height: 1.35; }
.place-status:empty { margin: 0; }

.place-search {
  scroll-margin-top: 8rem; /* clears the sticky Settings bar */
  margin-top: 0.5rem;
  padding: 1.25rem;
  border: 0.25rem solid var(--fg);
  border-radius: 0.75rem;
}
.search-title { margin-bottom: 0.75rem; font-size: 1.9rem; }
.search-label { display: block; margin-bottom: 0.5rem; font-size: 1.5rem; }
.search-row { display: flex; flex-wrap: wrap; align-items: stretch; gap: 0.75rem 1rem; }
.search-input {
  flex: 1 1 18rem;
  min-width: 0;
  min-height: 4rem;
  padding: 0.5rem 0.9rem;
  border: 0.25rem solid var(--fg);
  border-radius: 0.6rem;
  background: var(--bg);
  color: var(--fg);
  font: inherit;
  font-size: 1.8rem;
}
.search-msg { margin-top: 1rem; font-size: 1.5rem; line-height: 1.35; }
.search-msg:empty { margin: 0; }
.search-results { display: flex; flex-direction: column; gap: 0.75rem; margin-top: 1rem; padding: 0; list-style: none; }
.search-results:empty { margin: 0; }
.result-btn {
  width: 100%;
  min-height: 4rem;
  padding: 0.7rem 1.2rem;
  border: 0.25rem solid var(--fg);
  border-radius: 0.6rem;
  font-size: 1.7rem;
  text-align: left;
}

.credits { padding-top: 1.5rem; font-size: 1.2rem; line-height: 1.4; }
.credits a { color: inherit; text-decoration: underline; text-underline-offset: 0.15em; }

.version { padding-top: 1rem; font-size: 1.1rem; }
.update-note {
  margin-top: 0.75rem;
  padding: 0.6rem 0.9rem;
  border: 0.2rem solid var(--fg);
  border-radius: 0.5rem;
  font-size: 1.4rem;
  line-height: 1.35;
}

.intro { max-width: 40em; margin: 1.25rem 0 1.5rem; font-size: 1.5rem; line-height: 1.4; }

.swatches {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr));
  gap: 1.5rem;
}

/* Each swatch carries its own data-bg / data-palette, so it shows that theme no matter which is active. */
.swatch {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 1.25rem;
  border: 0.25rem solid var(--frame);
  border-radius: 1rem;
  background: var(--bg);
  color: var(--fg);
}
.swatch[aria-pressed="true"] { outline: 0.5rem solid var(--frame); outline-offset: 0.3rem; }
.sw-sample { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.75rem 1.25rem; }
.sw-num { font-size: min(4.5rem, calc((100vw - 7rem) / 2.5)); font-weight: 800; line-height: 0.95; }
.sw-temp { width: 1.6rem; height: 4rem; border-radius: 0.4rem; background: var(--temp); }
.sw-rain { width: 3rem; height: 2.5rem; background: var(--rain); }
.sw-name { font-size: 1.5rem; }
.sw-chosen {
  padding: 0.25rem 0.7rem;
  border-radius: 0.4rem;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 1.2rem;
  visibility: hidden;
}
.swatch[aria-pressed="true"] .sw-chosen { visibility: visible; }

/* --- Narrow screens (phones, small windows) --- */

@media (max-width: 40rem) {
  .view { padding-inline: 1rem; }
  /* Full width; at the largest text sizes the words wrap under the speaker icon instead of overflowing. */
  .read-btn { width: 100%; min-width: 0; margin-left: 0; padding-inline: 0.8rem; flex-wrap: wrap; }

  /* Phones: side arrows would leave the charts almost no room, so they move below what they move,
     as two wide buttons side by side. The town name gets its own line above its arrows. */
  .place-bar,
  .chart-body {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas: "main main" "prev next";
    row-gap: 0.75rem;
  }
  .place-title,
  .chart-body > :not(.arrow-btn) { grid-area: main; }
  .place-bar > .arrow-btn:first-child,
  .chart-body > .arrow-btn:first-child { grid-area: prev; }
  .place-bar > .arrow-btn:last-child,
  .chart-body > .arrow-btn:last-child { grid-area: next; }
  .place-bar .arrow-btn,
  .chart-body .arrow-btn { width: auto; min-height: 4.25rem; }
  .single-place .place-bar { grid-template-areas: "main"; }

  /* Tighter spacing around the hourly numbers, so a phone fits three time blocks instead of two. */
  .hg { --hg-label-gap: 0.35rem; }
  .hg-cell { padding-inline: 0.25rem; }
  .hg-tick { padding-left: 0.35rem; }

  /* Very large text on a small phone: a word too long for the screen ("Temperature") breaks onto the
     next line, with a hyphen where the browser can, instead of running off the edge. Numbers never
     break: they are sized to fit instead. */
  main { overflow-wrap: anywhere; -webkit-hyphens: auto; hyphens: auto; }
  .now-temp, .size-sample-big, .sw-num, .temp-num, .rain-num, .hg-tick, .day-name { overflow-wrap: normal; }
  .place-row-name { min-width: 0; }
}
