:root {
  --bg: #f4f2ee;
  --surface: #ffffff;
  --border: #e4e0d8;
  --text: #1d1c1a;
  --muted: #6d6a64;
  --accent: #c2410c;
  --action: #2563eb; /* buttons and choices in Settings and its dialogs */
  --warning: #c2410c;
  --danger: #b91c1c;
  --visited: #7b7770;
  --masthead-bg: #1d1c1a;
  --masthead-text: #f4f2ee;
  --masthead-muted: #b5b0a6;
  --masthead-border: #3a3834;
  --shadow: 0 1px 2px rgb(29 28 26 / 0.04);
  --serif: "New York", ui-serif, "Iowan Old Style", "Palatino Linotype", Georgia, serif;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #141413;
    --surface: #1e1d1b;
    --border: #2f2d2a;
    --text: #ebe8e2;
    --muted: #9a958c;
    --accent: #f08a4b;
    --action: #3b82f6;
    --warning: #f08a4b;
    --danger: #dc2626;
    --visited: #86827a;
    --masthead-bg: #0c0c0b;
    --masthead-text: #ebe8e2;
    --masthead-muted: #9a958c;
    --masthead-border: #2f2d2a;
    --shadow: none;
  }
}

/* With a daily photo behind the page, surfaces turn translucent and blur what's under them.
   Cards let more of the photo through (--card-bg), unless the reader chose solid cards. */
.has-backdrop {
  --surface: rgb(255 255 255 / 0.86);
  --card-bg: rgb(255 255 255 / 0.68);
  --border: rgb(29 28 26 / 0.12);
  --masthead-bg: rgb(12 12 11 / 0.55);
  --masthead-border: rgb(255 255 255 / 0.18);
}

@media (prefers-color-scheme: dark) {
  .has-backdrop {
    --surface: rgb(24 23 21 / 0.82);
    --card-bg: rgb(24 23 21 / 0.62);
    --border: rgb(255 255 255 / 0.1);
    --masthead-bg: rgb(0 0 0 / 0.55);
  }
}

/* Density (Customise): how much fits on the page. Spacious, the default, leaves wide gaps
   and fewer, wider columns so more of the photo shows; Compact packs in the most. */
:root {
  --gutter: clamp(20px, 3vw, 48px);
  --gap: 22px;
  --column-width: 380px; /* layout.js reads this to count columns */
  --card-pad: 16px 20px 8px;
  --card-radius: 12px;
  --card-font: 15px;
  --item-pad: 10px;
}

.density-balanced {
  --gutter: clamp(16px, 2vw, 32px);
  --gap: 16px;
  --column-width: 330px;
  --card-pad: 13px 16px 6px;
  --card-radius: 10px;
  --card-font: 14px;
  --item-pad: 8px;
}

.density-compact {
  --gutter: 16px;
  --gap: 12px;
  --column-width: 300px;
  --card-pad: 10px 12px 4px;
  --card-radius: 8px;
  --card-font: 14px;
  --item-pad: 6px;
}

@media (min-width: 1200px) {
  .density-compact { --gutter: 20px; }
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 14px/1.35 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
}

a { color: inherit; text-decoration: none; }

.backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.has-backdrop .masthead {
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  backdrop-filter: blur(16px) saturate(1.3);
}

.has-backdrop .card {
  background: var(--card-bg);
  -webkit-backdrop-filter: blur(6px) saturate(1.2);
  backdrop-filter: blur(6px) saturate(1.2);
}

/* "Solid cards" in Customise: no photo behind the cards. */
.solid-cards .has-backdrop .card {
  background: #ffffff;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

@media (prefers-color-scheme: dark) {
  .solid-cards .has-backdrop .card { background: #1e1d1b; }
}

/* Bottom-right hotspot: hover or focus it to fade the page and see the photo in full.
   It's small so it doesn't cover the cards, but a screen corner is easy to hit.
   The short delay stops a pass of the pointer through the corner from triggering it. */
.masthead, .tabs, .grid { transition: opacity 0.3s ease; }

body:has(.peek:hover, .peek:focus-within) :is(.masthead, .tabs, .grid) {
  opacity: 0;
  pointer-events: none;
  transition-delay: 0.2s;
}

.peek {
  position: fixed;
  right: 0;
  bottom: 0;
  z-index: 10;
  width: 40px;
  height: 40px;
  outline: none;
}

/* A translucent quarter-circle tab tucked into the corner shows where the hotspot is. */
.peek-marker {
  position: absolute;
  bottom: 0;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: flex-end;
  padding: 8px;
  color: rgb(255 255 255 / 0.92);
  background: rgb(0 0 0 / 0.5);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.18);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  transition: opacity 0.3s ease;
}

.peek-marker { right: 0; justify-content: flex-end; border-top-left-radius: 100%; opacity: 0.5; }

.peek-marker svg { display: block; }

.peek:is(:hover, :focus-within) .peek-marker { opacity: 0; }

.peek-caption {
  position: absolute;
  bottom: 12px;
  display: grid;
  gap: 3px;
  width: max-content;
  max-width: min(440px, calc(100vw - 24px));
  padding: 10px 14px;
  border-radius: 10px;
  font-size: 13px;
  color: #fff;
  background: rgb(0 0 0 / 0.55);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

.peek-caption { right: 12px; text-align: right; }

.peek:is(:hover, :focus-within) .peek-caption {
  opacity: 1;
  pointer-events: auto;
  transition-delay: 0.2s;
}

.peek:focus-visible .peek-caption { outline: 2px solid var(--accent); outline-offset: 2px; }

.peek-credit { color: rgb(255 255 255 / 0.75); font-size: 12px; }

.peek-caption a { margin-top: 3px; font-weight: 600; }
.peek-caption a:hover { text-decoration: underline; }

.wrap { padding: 0 var(--gutter); }

.masthead {
  position: relative;
  z-index: 15; /* above the cards */
  background: var(--masthead-bg);
  color: var(--masthead-text);
}

.masthead .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-block: 8px;
  min-height: 52px;
}

.title {
  display: flex;
  align-items: baseline;
  gap: 14px;
  min-width: 0;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  align-self: center;
  color: inherit;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1;
  text-decoration: none;
}

.brand-mark { display: block; width: 32px; height: 24px; }

/* ".net" sits back a little, as in the logo artwork. */
.brand-name span { font-weight: 500; opacity: 0.72; }

.date { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--masthead-muted); font-size: 13px; white-space: nowrap; }
/* When space is short the date gives way, so the buttons never slide under the search box. */
.brand { flex: none; }

/* Compact search box between the title and the weather; it takes the spare width. */
.search { flex: 1 1 200px; max-width: 420px; min-width: 0; }

.search input {
  width: 100%;
  height: 30px;
  padding: 0 12px;
  border: 1px solid var(--masthead-border);
  border-radius: 15px;
  color: var(--masthead-text);
  background: rgb(255 255 255 / 0.1);
  font: inherit;
  font-size: 13px;
}

.search input::placeholder { color: var(--masthead-muted); }
.search input:focus { outline: none; border-color: var(--accent); background: rgb(255 255 255 / 0.16); }


.weather {
  display: flex;
  align-items: center;
  gap: 18px;
  min-width: 0;
}

.weather.is-stale { opacity: 0.6; }

.weather .now {
  display: flex;
  align-items: center;
  gap: 8px;
}

.weather .icon { font-size: 22px; line-height: 1; }

.weather .temp {
  font-size: 22px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.weather .summary { font-size: 13px; line-height: 1.25; }

.weather .detail {
  display: block;
  color: var(--masthead-muted);
  font-size: 12px;
}

.weather .hours {
  display: flex;
  gap: 4px;
  margin: 0;
  padding: 0 0 0 18px;
  list-style: none;
  border-left: 1px solid var(--masthead-border);
}

.weather .hours li {
  display: grid;
  justify-items: center;
  min-width: 40px;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.weather .hour { color: var(--masthead-muted); }

/* Rain chart: one blue, brighter for heavier rain (validated against the dark masthead). */
.rain {
  --rain-light: #3987e5;
  --rain-moderate: #86b6ef;
  --rain-heavy: #cde2fb;
  display: grid;
  grid-template: "bars caption" auto "axis caption" auto / auto auto;
  align-items: center;
  column-gap: 10px;
  row-gap: 2px;
  margin: 0;
  padding-left: 18px;
  border-left: 1px solid var(--masthead-border);
  font-size: 10px;
  line-height: 1.2;
}

/* The summary sits beside the bars, so the chart doesn't make the masthead taller. */
.rain figcaption {
  grid-area: caption;
  max-width: 13em;
  font-size: 12px;
  line-height: 1.25;
}

.rain-bars {
  display: flex;
  align-items: flex-end;
  grid-area: bars;
  gap: 2px;
  height: 18px;
  border-bottom: 1px solid var(--masthead-muted);
}

/* Each slot spans the full height so its tooltip is easy to hover. */
.rain .slot {
  display: flex;
  align-items: flex-end;
  width: 4px;
  height: 100%;
}

.rain .bar {
  width: 100%;
  min-height: 3px; /* drizzle stays visible */
  border-radius: 2px 2px 0 0;
}

.rain .is-light { background: var(--rain-light); }
.rain .is-moderate { background: var(--rain-moderate); }
.rain .is-heavy { background: var(--rain-heavy); }

.rain-axis {
  grid-area: axis;
  display: flex;
  justify-content: space-between;
  color: var(--masthead-muted);
  font-variant-numeric: tabular-nums;
}

@media (max-width: 1000px) {
  .rain { display: none; }
}

/* The weather in the masthead opens the full-screen forecast: a button laid over all of it
   takes the click, and lights the area up on hover so it's plain that it's one target. */
.weather { position: relative; }

.weather-open {
  position: absolute;
  inset: -6px -10px;
  z-index: 1;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 10px;
  background: transparent;
  color: var(--masthead-text);
  font: inherit;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
}

/* "Full forecast", hung on the box's bottom edge, clear of the weather itself. */
.weather-open span {
  position: absolute;
  right: 12px;
  bottom: -9px;
  padding: 2px 8px;
  border: 1px solid rgb(255 255 255 / 0.3);
  border-radius: 999px;
  background: #2a2926;
  font-size: 10px;
  line-height: 1.3;
  font-weight: 600;
  letter-spacing: 0.03em;
  opacity: 0;
  transform: translateY(3px);
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.weather-open:is(:hover, :focus-visible, [aria-expanded="true"]) {
  border-color: rgb(255 255 255 / 0.3);
  background: rgb(255 255 255 / 0.12);
  box-shadow: 0 6px 20px rgb(0 0 0 / 0.25);
}

.weather-open:focus-visible { outline: 2px solid var(--masthead-text); outline-offset: 2px; }
.weather-open:is(:hover, :focus-visible, [aria-expanded="true"]) span { opacity: 1; transform: none; }

/* The weather screen. A sky to suit the weather now fills the window below the masthead; the canvas
   (weather-screen.js) draws its rain, snow, cloud or sun over it, and the forecast sits on
   top, set large and quiet: a serif for the figures, small capitals for the headings. */
.weather-screen {
  --ws-text: oklch(97% 0.01 250);
  --ws-muted: oklch(97% 0.01 250 / 0.68);
  --ws-faint: oklch(97% 0.01 250 / 0.45);
  --ws-line: oklch(97% 0.01 250 / 0.16);
  --ws-rain: oklch(86% 0.08 235);
  --ws-serif: var(--serif);
  --ws-ease: var(--ease-out);
  position: fixed;
  inset: var(--ws-top, 0px) 0 0; /* weather-screen.js sets the masthead's height */
  z-index: 14; /* over the cards, under the masthead */
  width: 100vw;
  height: auto;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  /* The glow and the clouds fade out towards the masthead rather than being cut off by it. */
  --ws-top-fade: linear-gradient(transparent, #000 80px);
  overflow: hidden;
  background: var(--ws-sky);
  color: var(--ws-text);
  font-variant-numeric: tabular-nums;
}

.weather-screen[open] { animation: ws-fade 0.5s var(--ws-ease); }
html:has(.weather-screen[open]) { overflow: hidden; }
html:has(.weather-screen[open]) .masthead { position: sticky; top: 0; } /* in view however far down the page was */

/* While the screen is open the page behind it is hidden, which spares the browser the photo
   and the cards' blurs, and the same sky is painted behind everything. If the browser ever
   misses drawing the screen for a frame, what shows through is sky, not the photo. */
html:has(.weather-screen[open]) body { background: var(--ws-sky) fixed; }
html:has(.weather-screen[open]) body > :is(main, .tabs, .peek, .backdrop) { visibility: hidden; }

/* Skies, by day and by night, set on the page so the body can paint them too. All are deep
   enough for light text. */
:root { --ws-sky: linear-gradient(170deg, #1b4f86 0%, #2f6fae 45%, #5b8fbe 100%); }
:root:has(.weather-screen[data-sky="fair"]) { --ws-sky: linear-gradient(170deg, #24548a 0%, #3a74ab 50%, #6a93b8 100%); }
:root:has(.weather-screen[data-sky="cloud"]) { --ws-sky: linear-gradient(175deg, #3a434f 0%, #535d6a 55%, #66707c 100%); }
:root:has(.weather-screen[data-sky="fog"]) { --ws-sky: linear-gradient(180deg, #4b545d 0%, #646d75 60%, #737b82 100%); }
:root:has(.weather-screen[data-sky="drizzle"]) { --ws-sky: linear-gradient(175deg, #2e3b4a 0%, #435265 60%, #536276 100%); }
:root:has(.weather-screen[data-sky="rain"]) { --ws-sky: linear-gradient(175deg, #232f3d 0%, #34445a 60%, #44556b 100%); }
:root:has(.weather-screen[data-sky="downpour"]) { --ws-sky: linear-gradient(175deg, #19212c 0%, #273343 60%, #344255 100%); }
:root:has(.weather-screen[data-sky="storm"]) { --ws-sky: linear-gradient(175deg, #15161f 0%, #252636 55%, #383649 100%); }
:root:has(.weather-screen[data-sky="snow"]) { --ws-sky: linear-gradient(175deg, #46566b 0%, #5f6f85 55%, #74839a 100%); }
:root:has(.weather-screen[data-time="night"]) { --ws-sky: linear-gradient(175deg, #070b17 0%, #0e1830 55%, #1c2b4a 100%); }
:root:has(.weather-screen[data-time="night"]:is([data-sky="cloud"], [data-sky="fog"], [data-sky="drizzle"], [data-sky="rain"], [data-sky="snow"])) { --ws-sky: linear-gradient(175deg, #0d1119 0%, #19202c 55%, #262f3e 100%); }
:root:has(.weather-screen[data-time="night"]:is([data-sky="downpour"], [data-sky="storm"])) { --ws-sky: linear-gradient(175deg, #07080d 0%, #11131c 55%, #1c1f2c 100%); }

/* Sunshine, and moonlight on a clear night: a glow high on the right, drawn once here rather
   than on the canvas every frame. By day, faint rays fan out from it. */
.weather-screen:is([data-sky="clear"], [data-sky="fair"])::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    repeating-conic-gradient(from 8deg at 82% 10%, rgb(255 236 200 / 0.05) 0deg 2.2deg, transparent 2.2deg 25.7deg),
    radial-gradient(circle at 82% 10%, rgb(255 226 170 / 0.5), rgb(255 205 140 / 0.18) 16%, transparent 62%);
  -webkit-mask-image: var(--ws-top-fade), radial-gradient(circle at 82% 10%, #000 30%, transparent 85%);
  mask-image: var(--ws-top-fade), radial-gradient(circle at 82% 10%, #000 30%, transparent 85%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
  pointer-events: none;
}

.weather-screen:is([data-sky="clear"], [data-sky="fair"])[data-time="night"]::before {
  background: radial-gradient(circle at 80% 14%, rgb(220 230 255 / 0.2), transparent 45%);
}

/* A test sky (#weather?test=…, weather-screen.js) says so at the top of the screen, between
   the place and Close. */
.weather-screen[data-test]::after {
  content: "Test sky: " attr(data-test);
  position: absolute;
  top: calc(clamp(14px, 2.6vh, 40px) + 9px);
  left: 50%;
  z-index: 2;
  padding: 5px 12px;
  border: 1px solid var(--ws-line);
  border-radius: 999px;
  background: rgb(0 0 0 / 0.45);
  color: var(--ws-text);
  font-size: 11px;
  letter-spacing: 0.04em;
  pointer-events: none;
  transform: translateX(-50%);
}

.ws-sky {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  -webkit-mask-image: var(--ws-top-fade);
  mask-image: var(--ws-top-fade);
  pointer-events: none;
}

.ws-content {
  position: relative;
  height: 100%;
  overflow-y: auto;
  padding: clamp(14px, 2.6vh, 40px) clamp(16px, 4.5vw, 72px) clamp(14px, 2vh, 48px);
  /* A gentle shade under the detail column keeps small text legible over the brightest skies. */
  background: linear-gradient(90deg, transparent 35%, rgb(6 10 18 / 0.22) 70%);
  scrollbar-width: thin;
  scrollbar-color: var(--ws-line) transparent;
}

.ws-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 40px; /* level with the Close button */
  padding-right: 120px;
}

.ws-place { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px; margin: 0; }
.ws-place strong { font-family: var(--ws-serif); font-size: clamp(20px, 2vw, 26px); font-weight: 500; letter-spacing: -0.01em; }
.ws-place span { color: var(--ws-muted); font-size: 14px; }
/* Close stays put while the forecast scrolls under it. */
.ws-close-form { position: absolute; top: clamp(14px, 2.6vh, 40px); right: clamp(16px, 4.5vw, 72px); z-index: 2; margin: 0; }

.ws-close {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 8px 0 14px;
  border: 1px solid var(--ws-line);
  border-radius: 999px;
  background: rgb(255 255 255 / 0.1);
  color: var(--ws-text);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
}

.ws-close:hover { background: rgb(255 255 255 / 0.2); border-color: rgb(255 255 255 / 0.3); }
.ws-close:focus-visible { outline: 2px solid var(--ws-text); outline-offset: 3px; }
.ws-close svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }

.ws-close kbd {
  padding: 3px 7px;
  border-radius: 999px;
  background: rgb(255 255 255 / 0.12);
  color: var(--ws-muted);
  font-family: inherit;
  font-size: 11px;
  font-weight: 500;
}

.ws-layout {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: clamp(32px, 6vw, 110px);
  max-width: 1320px;
  margin: clamp(8px, 2vh, 56px) auto 0;
}

/* Now: the temperature, as large as the window allows, then the week. */
.ws-now { align-self: start; }
.ws-now > * { animation: ws-rise 0.8s var(--ws-ease) both; }
.ws-now > :nth-child(2) { animation-delay: 0.06s; }
.ws-now > :nth-child(3) { animation-delay: 0.12s; }
.ws-now > :nth-child(4) { animation-delay: 0.18s; }
.ws-now > :nth-child(5) { animation-delay: 0.24s; }

.ws-big {
  margin: 0 0 0 -0.06em;
  font-family: var(--ws-serif);
  font-size: clamp(100px, min(19vw, 23vh), 300px); /* sized by the height too, so it all fits */
  font-weight: 200;
  line-height: 0.85;
  letter-spacing: -0.05em;
}

.ws-big span { color: var(--ws-faint); font-weight: 100; }

.ws-condition {
  margin: clamp(8px, 1.8vh, 18px) 0 4px;
  font-family: var(--ws-serif);
  font-size: clamp(26px, min(3vw, 4.4vh), 40px);
  font-style: italic;
  font-weight: 400;
  letter-spacing: -0.01em;
}

.ws-condition span { font-style: normal; font-size: 0.8em; }
.ws-range-text { margin: 0; color: var(--ws-muted); font-size: 15px; }

.ws-facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: clamp(14px, 3vh, 32px) 0 0;
  border-top: 1px solid var(--ws-line);
}

.ws-facts div { padding: clamp(5px, 0.9vh, 12px) 12px clamp(5px, 0.9vh, 12px) 0; border-bottom: 1px solid var(--ws-line); }
.ws-facts dt { color: var(--ws-muted); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; }
.ws-facts dd { margin: 4px 0 0; font-size: 17px; font-weight: 500; }
.ws-facts small { color: var(--ws-muted); font-size: 12px; font-weight: 400; }

/* The detail column */
.ws-detail { display: grid; gap: clamp(16px, 2.6vh, 52px); padding-top: 6px; }
.ws-section { animation: ws-rise 0.8s var(--ws-ease) both; }
.ws-section:nth-child(2) { animation-delay: 0.08s; }
.ws-section:nth-child(3) { animation-delay: 0.16s; }
.ws-section:nth-child(4) { animation-delay: 0.24s; }

.ws-section h3 {
  margin: 0 0 clamp(8px, 1.4vh, 14px);
  padding-bottom: clamp(5px, 0.9vh, 8px);
  border-bottom: 1px solid var(--ws-line);
  color: var(--ws-muted);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.ws-section ol { list-style: none; margin: 0; padding: 0; }
.ws-lead { margin: 0; font-family: var(--ws-serif); font-size: 22px; letter-spacing: -0.01em; }
.ws-lead .ws-icon { font-family: system-ui, sans-serif; }
.ws-sub { margin: 4px 0 0; color: var(--ws-muted); font-family: system-ui, sans-serif; font-size: 13px; letter-spacing: 0; }
.ws-h3-note { float: right; color: var(--ws-muted); font-size: 12px; font-weight: 400; letter-spacing: 0; text-transform: none; }
.ws-dim { color: var(--ws-muted); }
.ws-icon { font-size: 22px; line-height: 1.2; }
.ws-time, .ws-wind, .ws-tick { color: var(--ws-muted); font-size: 11px; }
.ws-temp { font-weight: 600; }
.ws-rain-text { color: var(--ws-rain); font-size: 11px; }

/* Rain today: one column per hour from midnight; hours gone are faded, the hour now marked.
   The scale is fixed (forecast.js), a third each for light, moderate and heavy rain, with the
   bands labelled in a gutter on the left. Heavier rain is brighter, as in the masthead. */
.ws-rain-chart {
  --ws-bar-h: clamp(56px, 9vh, 110px);
  --ws-rain-light: oklch(78% 0.1 240);
  --ws-rain-moderate: oklch(88% 0.08 235);
  --ws-rain-heavy: oklch(97% 0.03 230);
  position: relative;
  margin-top: clamp(8px, 1.6vh, 18px);
  padding-left: 62px;
}

.ws-bands {
  position: absolute;
  top: 14px;
  right: 0;
  left: 0;
  display: grid;
  grid-template-rows: repeat(3, 1fr);
  height: var(--ws-bar-h);
  pointer-events: none;
}

.ws-bands span {
  border-top: 1px dashed var(--ws-line);
  color: var(--ws-faint);
  font-size: 10px;
  letter-spacing: 0.04em;
  line-height: 1.6;
}

.ws-rain-chart ol {
  position: relative; /* over the band lines */
  display: grid;
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: column;
  gap: 3px;
  padding-top: 14px;
}

.ws-rain-chart li { display: grid; grid-template-rows: var(--ws-bar-h) auto; gap: 6px; }

.ws-bar {
  position: relative;
  border-bottom: 1px solid var(--ws-line);
}

.ws-chance, .ws-amount {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
}

.ws-chance { top: 0; background: rgb(255 255 255 / 0.2); } /* opacity: the chance, set inline */
.ws-amount { min-height: 3px; border-radius: 3px 3px 0 0; background: var(--ws-rain-light); }
.ws-amount.is-moderate { background: var(--ws-rain-moderate); }
.ws-amount.is-heavy { background: var(--ws-rain-heavy); box-shadow: 0 0 12px oklch(97% 0.03 230 / 0.4); }
.ws-rain-chart .is-past :is(.ws-bar, .ws-tick) { opacity: 0.35; }
.ws-rain-chart li { position: relative; }
.ws-rain-chart li:hover .ws-bar { box-shadow: inset 0 0 0 999px rgb(255 255 255 / 0.08); }

/* An hour's popover: over its column, at once on hover. */
.ws-tip {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  z-index: 3;
  display: grid;
  gap: 4px;
  padding: 8px 10px;
  border: 1px solid var(--ws-line);
  border-radius: 8px;
  background: oklch(24% 0.03 250 / 0.94);
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.3);
  color: var(--ws-text);
  font-size: 12px;
  line-height: 1.3;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, 4px);
  transition: opacity 0.08s ease, transform 0.08s ease, visibility 0s linear 0.08s;
}

.ws-tip.is-start { left: 0; transform: translateY(4px); }
.ws-tip.is-end { right: 0; left: auto; transform: translateY(4px); }
.ws-rain-chart li:hover .ws-tip { opacity: 1; visibility: visible; transform: translate(-50%, 0); transition-delay: 0s; }
.ws-rain-chart li:hover .ws-tip:is(.is-start, .is-end) { transform: none; }
.ws-tip-time { color: var(--ws-muted); font-size: 11px; letter-spacing: 0.04em; }
.ws-tip-rain { display: flex; align-items: center; gap: 6px; }
.ws-tip-rain b { font-weight: 600; }
.ws-dot { width: 8px; height: 8px; border-radius: 2px; }
.ws-dot.is-light { background: var(--ws-rain-light); }
.ws-dot.is-moderate { background: var(--ws-rain-moderate); }
.ws-dot.is-heavy { background: var(--ws-rain-heavy); }
.ws-tip-chance { display: flex; align-items: center; gap: 6px; color: var(--ws-muted); font-size: 11px; }
.ws-tip-meter { width: 40px; height: 4px; border-radius: 2px; background: rgb(255 255 255 / 0.15); overflow: hidden; }
.ws-tip-meter span { display: block; height: 100%; background: var(--ws-text); }
.ws-tick { text-align: center; white-space: nowrap; }
.ws-rain-chart .is-now .ws-tick { color: var(--ws-text); font-weight: 700; }
.ws-rain-chart .is-now .ws-bar { border-bottom: 2px solid var(--ws-text); background: linear-gradient(var(--ws-faint), var(--ws-faint)) 50% 0 / 1px 100% no-repeat; } /* a hairline down the hour now */

/* The key sits above the chart, at the right. */
.ws-legend {
  position: absolute;
  top: -3px;
  right: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  line-height: 1;
  color: var(--ws-muted);
  font-size: 11px;
}

.ws-legend span { width: 8px; height: 8px; border-radius: 2px; }
.ws-legend span + span, .ws-key-chance { margin-left: 10px; }
.ws-legend .ws-key-amount { width: 14px; background: linear-gradient(90deg, var(--ws-rain-light), var(--ws-rain-moderate), var(--ws-rain-heavy)); }
.ws-key-chance { background: rgb(255 255 255 / 0.22); }

/* The next 24 hours in two rows of twelve. Each hour's lines share rows (a subgrid) with the
   rest of its row of hours, so they stay in line. */
.ws-hours {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  row-gap: 2px;
}

.ws-hours li {
  display: grid;
  grid-row: span 4;
  grid-template-rows: subgrid;
  justify-items: center;
  padding-bottom: clamp(4px, 1vh, 14px); /* the space between rows of hours */
  text-align: center;
}

.ws-hours .is-new-day .ws-time { color: var(--ws-text); font-weight: 700; }

/* Tomorrow */
.ws-tomorrow .ws-sub { margin: 4px 0 clamp(10px, 1.8vh, 16px); }

.ws-parts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
}

.ws-parts li {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: "icon name" "icon temp" "icon detail";
  align-content: start;
  column-gap: 10px;
}

.ws-parts .ws-icon { grid-area: icon; font-size: 28px; }
.ws-part { grid-area: name; color: var(--ws-muted); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; }
.ws-parts .ws-temp { grid-area: temp; font-family: var(--ws-serif); font-size: 20px; font-weight: 400; }
.ws-part-detail { grid-area: detail; font-size: 11px; }

/* The week, compact, each day's range of temperatures on one scale: cool to warm. */
.ws-week { margin-top: clamp(14px, 2.6vh, 36px); }

.ws-week li {
  position: relative;
  display: grid;
  grid-template-columns: 76px 26px minmax(0, 1fr) 30px minmax(60px, 130px) 30px;
  align-items: center;
  gap: 10px;
  padding: clamp(1px, 0.3vh, 5px) 0;
  border-bottom: 1px solid var(--ws-line);
}

.ws-day { font-weight: 600; }

/* Picking a day: a button over the whole row takes the click. */
.ws-day-pick {
  position: absolute;
  inset: 0 -8px;
  z-index: 1;
  border: 0;
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
  transition: background 0.15s ease;
}

.ws-day-pick:hover { background: rgb(255 255 255 / 0.07); }
.ws-day-pick:focus-visible { outline: 2px solid var(--ws-text); outline-offset: -2px; }
.ws-day-pick[aria-pressed="true"] { background: rgb(255 255 255 / 0.13); box-shadow: inset 2px 0 0 var(--ws-text); }

.ws-back {
  float: right;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: -4px 0 0;
  padding: 3px 10px 3px 6px;
  border: 1px solid var(--ws-line);
  border-radius: 999px;
  background: rgb(255 255 255 / 0.08);
  color: var(--ws-text);
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  cursor: pointer;
}

.ws-back:hover { background: rgb(255 255 255 / 0.18); }
.ws-back:focus-visible { outline: 2px solid var(--ws-text); outline-offset: 2px; }
.ws-back svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.ws-week .ws-icon { font-size: 19px; text-align: center; }
.ws-week .ws-rain-text { text-align: right; white-space: nowrap; }
.ws-low { color: var(--ws-muted); text-align: right; }
.ws-high { font-weight: 600; }

.ws-range {
  position: relative;
  height: 4px;
  border-radius: 2px;
  background: rgb(255 255 255 / 0.12);
}

.ws-range span {
  position: absolute;
  inset-block: 0;
  border-radius: 2px;
  background: linear-gradient(90deg, #8cc4f0, #f5c46a);
}

@keyframes ws-fade { from { opacity: 0; } }
@keyframes ws-rise { from { opacity: 0; transform: translateY(14px); } }

/* A refresh while open swaps the forecast in without its entrance (forecast.js). */
@media (prefers-reduced-motion: reduce) {
  .weather-screen[open], .ws-now > *, .ws-section { animation: none; }
}

.weather-screen[data-refreshed] :is(.ws-now > *, .ws-section) { animation: none; }
.weather-screen[data-picking] :is(.ws-now > *, .ws-week) { animation: none; } /* a day picked: only the detail moves */

@media (max-width: 960px) {
  .ws-layout { grid-template-columns: minmax(0, 1fr); }
  .ws-content { background: rgb(6 10 18 / 0.12); }
}

@media (max-width: 600px) {
  .ws-close { padding: 0 12px; }
  .ws-close kbd { display: none; }
  .ws-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ws-hours { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .ws-parts { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .ws-rain-chart { --ws-bar-h: 90px; padding-left: 54px; }
  .ws-rain-chart ol { gap: 2px; }
  .ws-week li { grid-template-columns: 66px 24px minmax(0, 1fr) 28px minmax(30px, 70px) 28px; gap: 8px; }
}

@media (max-width: 900px) {
  .weather .hours { display: none; }
}

@media (max-width: 700px) {
  .masthead .wrap { flex-wrap: wrap; }
  .search { order: 3; flex-basis: 100%; max-width: none; }
}

@media (max-width: 560px) {
  .date { display: none; }
  .weather .detail { display: none; }
}

.tabs {
  display: flex;
  justify-content: center;
  gap: 4px;
  overflow-x: auto;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}

.tabs a {
  padding: 12px 14px;
  font-weight: 600;
  color: var(--muted);
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}

.tabs a[aria-current="page"] { color: var(--text); border-bottom-color: var(--accent); }

/* Multi-column flow packs cards of different heights without row gaps. */
.grid {
  position: relative; /* reorder.js measures cards from here */
  columns: var(--column-width);
  column-gap: var(--gap);
  padding-block: var(--gap);
}

/* layout.js swaps the flow for balanced flex columns once it has measured the cards. */
.grid.packed {
  display: flex;
  align-items: flex-start;
  columns: auto;
}

.grid.packed .column { flex: 1 1 0; min-width: 0; }

/* Packed columns fit the window, so the page itself doesn't scroll: each column keeps its
   cards at full height except the last, which stops at the bottom of the window and
   scrolls its stories instead. (layout.js measures cards unpacked, so this doesn't skew
   the packing.) With more cards than fit (`scrolls`, from layout.js), or a single column on
   a narrow screen, the page scrolls as usual. */
html { scrollbar-gutter: stable; } /* a page scrollbar coming and going mustn't change the column count */

body:has(.grid.packed:not(.scrolls)) {
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

body:has(.grid.packed) > :is(.masthead, .tabs) { flex: none; }

.grid.packed { flex: 1 1 auto; min-height: 0; padding-bottom: 0; }

.grid.packed .column {
  display: flex;
  flex-direction: column;
  max-height: 100%;
  overflow-y: auto; /* only if a column's cards can't all fit even when squeezed */
  scrollbar-width: none;
}

.grid.packed .card { display: flex; flex-direction: column; flex: none; max-height: calc(100% - var(--gap)); }
.grid.packed .card:last-child { flex: 0 1 auto; min-height: 160px; }
.grid.packed .card > :is(h2, .stale) { flex: none; }

.grid.packed.scrolls { padding-bottom: 0; }
.grid.packed.scrolls .column { max-height: none; overflow: visible; }
.grid.packed.scrolls .card { max-height: none; }
.grid.packed.scrolls .card:last-child { min-height: 0; }


/* Filling the screen (layout.js): every column runs the full height, its stories spaced out
   to share the spare room, and its last card stretched over what's left, so all the
   columns end level. */
.grid.filled { align-items: stretch; }
.grid.filled .card:last-child { flex-grow: 1; }
.grid.filled .item { padding-block: calc(var(--item-pad) + var(--story-spread, 0px)); }

.grid.packed .card .items {
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}

.card {
  break-inside: avoid;
  margin: 0 0 var(--gap);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--card-radius);
  padding: var(--card-pad);
  font-size: var(--card-font);
  box-shadow: var(--shadow);
  min-width: 0;
}

.card h2 {
  margin: 0;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
  font-size: 15px;
  font-weight: 700;
}

.card h2 a:hover { color: var(--accent); }

.items { list-style: none; margin: 0; padding: 0; }

.item {
  display: flex;
  gap: 10px;
  padding: var(--item-pad) 0;
  border-bottom: 1px solid var(--border);
}

.item:last-child { border-bottom: 0; }

/* Spare stories (buildCards) show only where layout.js finds room to fill the screen, and it
   cuts stories that don't fit. The last one showing loses its rule like a last child. */
.item.extra:not(.show), .item.cut { display: none; }
.item:has(+ .item:is(.cut, .extra:not(.show))) { border-bottom: 0; }

.thumb {
  flex: none;
  width: 54px;
  height: 36px;
  border-radius: 6px;
  object-fit: cover;
  background: var(--border);
}

.thumb-empty {
  display: grid;
  place-items: center;
  color: var(--muted);
  font-size: 15px;
  font-weight: 700;
}

.body { min-width: 0; }

.headline {
  display: block;
  font-weight: 500;
  overflow-wrap: anywhere;
}

.headline:hover { color: var(--accent); }
.headline:visited { color: var(--visited); }

.meta {
  margin-top: 1px;
  color: var(--muted);
  font-size: 12px;
}

.meta a:hover { color: var(--accent); text-decoration: underline; }

.source { font-weight: 600; }

.empty { color: var(--muted); margin: 14px 0; }

.stale {
  margin: 4px 0 2px;
  color: var(--muted);
  font-size: 12px;
}

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }

/* With a customised layout saved, page.js draws the reader's cards; hide the default ones until then. */
.customised .grid { visibility: hidden; }

/* Settings and the dialogs opened from it use blue for buttons, choices and focus rings. */
.settings-screen, .setup-screen, .customise { --accent: var(--action); }

/* Dialogs (history, removing a card, starting over) */
.customise {
  width: min(520px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  padding: 18px 18px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  color: var(--text);
  background: var(--bg);
  box-shadow: 0 20px 50px rgb(0 0 0 / 0.3);
}

.customise::backdrop { background: rgb(0 0 0 / 0.45); }

.customise {
  --field: var(--surface);
  --field-hover: color-mix(in srgb, var(--text) 5%, var(--surface));
  --glass-line: var(--border);
  padding: 20px 20px 16px;
  border-radius: 16px;
}

.customise h2 { margin: 0 0 6px; font-family: var(--serif); font-size: 22px; font-weight: 500; letter-spacing: -0.01em; }

.customise-head p { margin: 0 0 12px; color: var(--muted); font-size: 13px; }

.card-list {
  display: grid;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.card-list li {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 8px 6px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
}

.card-list li.is-hidden { opacity: 0.6; }

.card-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  min-width: 0;
  font-weight: 600;
  cursor: pointer;
}

.card-limit { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: 12px; }

.card-limit input { width: 3.2em; }

.card-move { display: flex; gap: 2px; }

:is(.customise, .settings-screen) button,
:is(.customise, .settings-screen) input[type=number] {
  min-height: 28px;
  padding: 2px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  background: var(--surface);
  font: inherit;
  font-size: 13px;
}

:is(.customise, .settings-screen) input[type=number] { padding-inline: 6px; }

:is(.customise, .settings-screen) input[type=checkbox] { accent-color: var(--accent); width: 16px; height: 16px; margin: 0; }

.card-move button { width: 30px; padding: 0; }

:is(.customise, .settings-screen) button:not(:disabled) { cursor: pointer; }
:is(.customise, .settings-screen) button:not(:disabled):hover { border-color: var(--muted); }
:is(.customise, .settings-screen) button:disabled { opacity: 0.35; }

:is(.customise, .settings-screen) .primary { color: #fff; background: var(--accent); border-color: var(--accent); font-weight: 600; }

.customise-status { min-height: 1.35em; margin: 10px 0 0; color: var(--muted); font-size: 12px; }

.customise-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 6px;
}

.customise-actions .primary { margin-left: auto; }

@media (max-width: 480px) {
  .card-limit { font-size: 0; gap: 0; } /* the number box is enough on narrow screens */
  .density-options small { display: none; }
}

/* Dragging cards around the page (reorder.js) */
.card { -webkit-touch-callout: none; } /* a long press picks the card up instead */
.card > h2 { cursor: grab; }

.card.is-lifted {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 20;
  margin: 0;
  pointer-events: none;
  box-shadow: 0 18px 40px rgb(0 0 0 / 0.35);
  opacity: 0.96;
}

/* Where the card will land. */
.card-placeholder {
  margin: 0 0 12px;
  border: 2px dashed var(--accent);
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

.is-reordering, .is-reordering * { cursor: grabbing !important; user-select: none; }
/* Every column is somewhere to drop a card, even an empty one. */
.is-reordering .grid.packed { align-items: stretch; }
.is-reordering .grid.packed .column {
  min-height: 120px;
  border-radius: 10px;
  outline: 1px dashed color-mix(in srgb, var(--muted) 55%, transparent);
  outline-offset: 4px;
}

/* Settings: the page's density, a three-way choice */
.density { margin: 0 0 14px; padding: 0; border: 0; }
.density legend { padding: 0; margin-bottom: 6px; font-size: 13px; font-weight: 600; }

.density-options {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
}

.density-options label { position: relative; cursor: pointer; }
.density-options input { position: absolute; opacity: 0; pointer-events: none; }

.density-options span {
  display: block;
  padding: 6px 8px;
  border-radius: 6px;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
}

.density-options label:hover span { color: var(--text); }
.density-options small { display: block; margin-top: 1px; font-size: 11px; font-weight: 400; opacity: 0.8; }
.density-options input:checked + span { color: #fff; background: var(--accent); }
.density-options input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Settings: fitting cards to the screen, and the column each card is in */
.arrange-toggle {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0 0 12px;
  font-weight: 600;
  cursor: pointer;
}

.arrange-toggle input { margin-top: 3px; }
.arrange-toggle small { display: block; margin-top: 2px; color: var(--muted); font-size: 12px; font-weight: 400; }
.card-column { color: var(--muted); font-size: 12px; font-weight: 400; white-space: nowrap; }

/* Settings: drag handles, removing a feed, adding one */
.drag-handle {
  flex: none;
  margin-right: -4px;
  color: var(--muted);
  font-size: 16px;
  line-height: 1;
  cursor: grab;
  touch-action: none; /* lets a finger drag the row instead of scrolling */
  user-select: none;
}

.card-list li.is-dragging {
  position: relative;
  z-index: 1;
  border-color: var(--accent);
  box-shadow: 0 6px 18px rgb(0 0 0 / 0.25);
  cursor: grabbing;
}

:is(.customise, .settings-screen) .card-remove { width: 28px; padding: 0; color: var(--muted); font-size: 16px; }
:is(.customise, .settings-screen) .card-remove:hover { color: var(--accent); }

.add-feed { display: grid; gap: 6px; margin-top: 14px; }
.add-feed label { font-weight: 600; font-size: 13px; }
.add-feed-row { display: flex; gap: 8px; }

.add-feed input {
  flex: 1;
  min-width: 0;
  min-height: 30px;
  padding: 2px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  background: var(--surface);
  font: inherit;
  font-size: 13px;
}

.add-feed input:focus { outline: none; border-color: var(--accent); }

/* The Settings screen (settings-screen.js) and the setup screen (setup.js): pages of their own at
   /settings and /settings/topics-and-sources, filling the window, with the same header and two
   columns of sections. Like the weather screen they set the page aside rather than cover it:
   the day's photo stays behind them, softly blurred under a veil, and the sections are frosted
   panels over it, headed in small capitals, with a serif title. */
.settings-screen,
.setup-screen {
  --veil: var(--bg);
  --glass: var(--surface);
  --glass-line: var(--border);
  --glass-shadow: 0 1px 2px rgb(29 28 26 / 0.05), 0 10px 30px -12px rgb(29 28 26 / 0.18);
  --field: var(--bg);
  --field-hover: color-mix(in srgb, var(--text) 6%, var(--bg));
  --pad: 24px;
  width: 100vw;
  max-width: none;
  height: 100dvh;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  color: var(--text);
  background: var(--veil);
}

@media (prefers-color-scheme: dark) {
  .settings-screen,
  .setup-screen {
    --glass-shadow: 0 10px 30px -12px rgb(0 0 0 / 0.5);
    --field: rgb(255 255 255 / 0.04);
    --field-hover: rgb(255 255 255 / 0.08);
  }
}

/* Over the photo: a light (or, in the dark, deep) veil, with panels that let a little through. */
:root:not(.no-backdrop) .has-backdrop :is(.settings-screen, .setup-screen) {
  --veil: linear-gradient(180deg, rgb(244 242 238 / 0.5), rgb(244 242 238 / 0.72));
  --glass: rgb(255 255 255 / 0.7);
  --glass-line: rgb(255 255 255 / 0.6);
  --field: rgb(244 242 238 / 0.75);
  --field-hover: rgb(236 233 227 / 0.9);
}

@media (prefers-color-scheme: dark) {
  :root:not(.no-backdrop) .has-backdrop :is(.settings-screen, .setup-screen) {
    --veil: linear-gradient(180deg, rgb(12 12 11 / 0.5), rgb(12 12 11 / 0.72));
    --glass: rgb(24 23 21 / 0.66);
    --glass-line: rgb(255 255 255 / 0.08);
    --field: rgb(0 0 0 / 0.22);
    --field-hover: rgb(255 255 255 / 0.06);
  }
}

.settings-screen::backdrop,
.setup-screen::backdrop { background: transparent; }

.settings-screen[open],
.setup-screen[open] { animation: ws-fade 0.35s var(--ease-out); }

/* While either is open the page behind steps away, leaving only the photo, blurred once (a
   static filter, so it costs nothing as the page scrolls). Settings also steps away while the
   setup screen is open over it. */
html:has(:is(.settings-screen, .setup-screen)[open]) { overflow: hidden; }
html:has(:is(.settings-screen, .setup-screen)[open]) body > :is(.masthead, main, .tabs, .peek, .setup-bar-wrap) { visibility: hidden; }
html:has(:is(.settings-screen, .setup-screen)[open]) .backdrop { filter: blur(36px) saturate(1.2); transform: scale(1.1); }
html:has(.setup-screen[open]) .settings-screen[open] { visibility: hidden; }
/* Opened over the weather screen, they set that aside too, and bring the photo back to blur. */
html:has(:is(.settings-screen, .setup-screen)[open]) .weather-screen[open] { visibility: hidden; }
html:has(.weather-screen[open]):has(:is(.settings-screen, .setup-screen)[open]) body > .backdrop { visibility: visible; }

.settings-content {
  box-sizing: border-box;
  height: 100%;
  overflow-y: auto;
  padding: 0 var(--pad) calc(var(--pad) + env(safe-area-inset-bottom));
  scrollbar-width: thin;
  scrollbar-color: var(--glass-line) transparent;
}

/* The header runs the full width, frosted, so the sections blur as they scroll under it. */
.settings-head {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 0 calc(var(--pad) * -1);
  padding: 18px max(var(--pad), calc((100% + var(--pad) * 2 - 1180px) / 2)) 16px;
  border-bottom: 1px solid var(--glass-line);
  background: color-mix(in srgb, var(--bg) 62%, transparent);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
  backdrop-filter: blur(18px) saturate(1.3);
}

.settings-head h1 {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(24px, 2.4vw, 30px);
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1.1;
}

.settings-head p { flex: 1; margin: 0; color: var(--muted); font-size: 13px; }

/* A message about the last change takes the place of the note about saving. */
.settings-status:empty,
.settings-head:has(.settings-status:not(:empty)) .settings-saved { display: none; }
.settings-head .settings-status { flex: 0 1 auto; margin-right: auto; }

.settings-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px 5px 10px;
  border-radius: 999px;
  color: var(--text);
  background: color-mix(in srgb, var(--accent) 12%, var(--glass));
  font-weight: 500;
  animation: ws-rise 0.4s var(--ease-out);
}

.settings-status::before {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
}

/* Back to Settings, from the setup screen. */
.setup-screen .settings-back { margin-right: -6px; padding-inline: 10px 14px; border-color: transparent; background: transparent; color: var(--muted); }
.setup-screen .settings-back:not(:disabled):hover { color: var(--text); background: var(--field); border-color: var(--glass-line); }
.setup-screen [hidden] { display: none; }

.settings-columns {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: 20px;
  max-width: 1180px;
  margin: 18px auto 0;
  align-items: start;
}

.settings-side { display: grid; gap: 16px; align-content: start; }

.settings-section {
  padding: 14px 20px 18px;
  border: 1px solid var(--glass-line);
  border-radius: 16px;
  background: var(--glass);
  box-shadow: var(--glass-shadow);
  animation: ws-rise 0.6s var(--ease-out) both;
}

/* The sections arrive one after another, down each column. */
.settings-side + .settings-side > :nth-child(1) { animation-delay: 0.04s; }
.settings-side > :nth-child(2) { animation-delay: 0.08s; }
.settings-side + .settings-side > :nth-child(2) { animation-delay: 0.12s; }
.settings-side > :nth-child(3) { animation-delay: 0.16s; }

/* A section that only leads somewhere else keeps its button beside the text. */
.settings-link { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: 16px; }
.settings-link h2 { grid-column: 1 / -1; }
.settings-link .settings-hint { margin: 0; }

/* Section headings in small capitals over a hairline, as on the weather screen. */
.settings-section h2 {
  margin: 0 0 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--glass-line);
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.settings-hint { margin: 0 0 12px; color: var(--muted); font-size: 13px; line-height: 1.5; text-wrap: pretty; }
.settings-hint strong { color: var(--text); font-weight: 600; }
.settings-section > :last-child { margin-bottom: 0; }

.settings-buttons { display: flex; flex-wrap: wrap; gap: 8px; }

/* Buttons are pills: quiet by default, blue for the main action, red text for starting over. */
:is(.settings-screen, .setup-screen, .customise) button {
  min-height: 34px;
  padding: 0 16px;
  border: 1px solid var(--glass-line);
  border-radius: 999px;
  color: var(--text);
  background: var(--field);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.15s, border-color 0.15s, color 0.15s, box-shadow 0.15s, transform 0.1s;
}

:is(.settings-screen, .setup-screen, .customise) button:not(:disabled):hover { border-color: color-mix(in srgb, var(--muted) 45%, transparent); background: var(--field-hover); }
:is(.settings-screen, .setup-screen, .customise) button:not(:disabled):active { transform: scale(0.97); }
:is(.settings-screen, .setup-screen, .customise) button:disabled { opacity: 0.4; cursor: default; }

:is(.settings-screen, .setup-screen, .customise) .primary {
  border-color: transparent;
  color: #fff;
  background: var(--accent);
  font-weight: 600;
  box-shadow: 0 4px 14px -4px color-mix(in srgb, var(--accent) 70%, transparent);
}

:is(.settings-screen, .setup-screen, .customise) .primary:not(:disabled):hover { border-color: transparent; background: color-mix(in srgb, var(--accent) 88%, #000); }
.settings-head .primary { min-width: 88px; }

/* Done shows its key, like Close on the weather screen. */
.settings-head kbd {
  margin: 0 -8px 0 8px;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgb(255 255 255 / 0.2);
  font-family: inherit;
  font-size: 11px;
  font-weight: 500;
}

.settings-screen .danger-outline { color: var(--danger); }
.settings-screen .danger-outline:not(:disabled):hover { border-color: color-mix(in srgb, var(--danger) 50%, transparent); background: color-mix(in srgb, var(--danger) 8%, var(--field)); }

/* The card list: rows set into the panel, picked out on hover. */
.settings-screen .card-list { gap: 6px; }

.settings-screen .card-list li {
  min-height: 44px;
  padding: 4px 6px 4px 12px;
  border-color: transparent;
  border-radius: 10px;
  background: var(--field);
  transition: background-color 0.15s, border-color 0.15s;
}

.settings-screen .card-list li:hover { background: var(--field-hover); }
.settings-screen .card-list li.is-dragging { border-color: var(--accent); background: var(--glass); }
.settings-screen .card-toggle { font-weight: 500; }
.settings-screen .card-list input[type=number] { min-height: 30px; border-radius: 8px; background: var(--glass); }
.settings-screen .card-move button { width: 30px; min-height: 30px; padding: 0; border-color: transparent; background: transparent; color: var(--muted); }
.settings-screen .card-move button:not(:disabled):hover { color: var(--text); background: var(--glass); }

.settings-screen .density-options,
.settings-screen .add-feed input { border-color: var(--glass-line); background: var(--field); }
.settings-screen .density-options { padding: 3px; border-radius: 12px; }
.settings-screen .density-options span { padding: 7px 8px; border-radius: 9px; transition: background-color 0.15s, color 0.15s; }
.settings-screen .density legend { margin-bottom: 8px; }
.settings-screen .add-feed { margin-top: 18px; }
.settings-screen .add-feed input { min-height: 36px; padding-inline: 14px; border-radius: 999px; }
.settings-screen .add-feed input:focus { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); }

/* On and off settings are switches, the label on the left. */
.arrange-toggle,
.setup-check { justify-content: space-between; }

.settings-screen .arrange-toggle { flex-direction: row-reverse; gap: 16px; margin: 0; padding: 10px 0; border-top: 1px solid var(--glass-line); font-weight: 500; }
.settings-screen .arrange-toggle:first-of-type { margin-top: 14px; }
.settings-screen .arrange-toggle:last-child { padding-bottom: 0; }
.settings-screen .arrange-toggle small { margin-top: 3px; line-height: 1.45; }

:is(.settings-screen, .setup-screen) :is(.arrange-toggle, .setup-check) input {
  -webkit-appearance: none;
  appearance: none;
  position: relative;
  flex: none;
  width: 36px;
  height: 22px;
  margin: 0;
  border-radius: 999px;
  background: color-mix(in srgb, var(--muted) 40%, transparent);
  cursor: pointer;
  transition: background-color 0.2s;
}

:is(.settings-screen, .setup-screen) :is(.arrange-toggle, .setup-check) input::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.3);
  transition: transform 0.2s var(--ease-out);
}

:is(.settings-screen, .setup-screen) :is(.arrange-toggle, .setup-check) input:checked { background: var(--accent); }
:is(.settings-screen, .setup-screen) :is(.arrange-toggle, .setup-check) input:checked::before { transform: translateX(14px); }
:is(.settings-screen, .setup-screen) :is(.arrange-toggle, .setup-check) input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.settings-screen .arrange-toggle input { margin-top: 1px; }

@media (max-width: 860px) {
  .settings-screen,
  .setup-screen { --pad: 16px; }
  .settings-columns { grid-template-columns: 1fr; gap: 14px; margin-top: 16px; }
  .settings-side { gap: 14px; }
  .settings-saved { display: none; }
  .settings-head { gap: 10px; padding-block: 12px; }
  .settings-head kbd { display: none; }
  .settings-head p { font-size: 12px; }
  .settings-head { justify-content: space-between; }
  .settings-section { padding: 14px 16px 16px; border-radius: 14px; }
  .settings-link { grid-template-columns: 1fr; row-gap: 12px; }
  .settings-link .settings-buttons { justify-self: start; }
  /* Back and Save share the top row; the title and intro take a row each below. */
  .setup-screen .settings-head { flex-wrap: wrap; row-gap: 4px; }
  .setup-screen .settings-head .settings-back { margin-left: -10px; }
  .setup-screen .settings-head .primary { margin-left: auto; }
  .setup-screen .settings-head h1 { order: 4; flex-basis: 100%; margin-top: 4px; }
  .setup-screen .setup-intro { order: 5; flex-basis: 100%; }
  .setup-option-label { width: 100%; }
}

@media (min-width: 861px) {
  .setup-screen .settings-columns { grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  .settings-screen[open], .setup-screen[open], .settings-section, .settings-status { animation: none; }
  :is(.settings-screen, .setup-screen) :is(.arrange-toggle, .setup-check) input::before { transition: none; }
}

/* Turned off on the setup screen (the early script sets these before the page paints). */
.no-weather .weather,
.no-backdrop .backdrop,
.no-backdrop .peek { display: none; }

/* Setup screen (setup.js): its page is laid out like Settings (above); these are its controls. */
.setup-screen .chip span,
.setup-screen .segmented { border-color: var(--glass-line); background: var(--field); }

.setup-hint { margin: -4px 0 8px; color: var(--muted); font-size: 12px; }
.setup-warning { min-height: 0; margin: 8px 0 0; color: var(--warning); font-size: 12px; }
.setup-warning:empty { display: none; }

.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chips + .chips { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--glass-line, var(--border)); }

/* Chips and segmented buttons are real inputs, hidden but focusable, inside their labels. */
.chip input,
.segmented input { position: absolute; opacity: 0; pointer-events: none; }

.chip span {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 34px;
  padding: 6px 14px 6px 11px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  font-size: 13px;
  cursor: pointer;
  user-select: none;
  transition: background-color 0.15s, border-color 0.15s, color 0.15s, transform 0.1s;
}

.chip:active span { transform: scale(0.97); }

.chip span::before {
  content: "+";
  width: 0.8em;
  color: var(--muted);
  font-weight: 600;
  text-align: center;
}

.chip:hover span { border-color: color-mix(in srgb, var(--muted) 45%, transparent); background: var(--field-hover, var(--surface)); }

.setup-screen .chip input:checked + span,
.chip input:checked + span {
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, var(--glass, var(--surface)));
  font-weight: 600;
}

.chip input:checked + span::before { content: "✓"; color: inherit; }

.chip input:focus-visible + span,
.segmented input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

.paywall {
  padding: 0 5px;
  border: 1px solid currentColor;
  border-radius: 4px;
  color: var(--muted);
  font-size: 10px;
  font-weight: 500;
  line-height: 1.5;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.segmented {
  display: inline-flex;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
}

.segmented label { position: relative; }

.segmented span {
  display: block;
  padding: 6px 16px;
  border-radius: 999px;
  color: var(--muted);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  user-select: none;
  transition: background-color 0.15s, color 0.15s;
}

.segmented label:hover span { color: var(--text); }

.segmented input:checked + span { color: #fff; background: var(--accent); font-weight: 600; box-shadow: 0 2px 8px -2px color-mix(in srgb, var(--accent) 70%, transparent); }

.setup-option {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  margin-bottom: 12px;
}

.setup-option-label { width: 4.5em; color: var(--muted); font-size: 13px; }

.setup-check { display: flex; flex-direction: row-reverse; align-items: center; gap: 16px; padding: 12px 0; border-top: 1px solid var(--glass-line, var(--border)); font-size: 13px; font-weight: 500; cursor: pointer; }
.setup-check:last-child { padding-bottom: 0; }
.setup-options .setup-option:last-of-type { margin-bottom: 16px; }
.chips[data-list="interests"]:empty { display: none; }


@media (prefers-reduced-motion: reduce) {
  .chip span { transition: none; }
}


/* Removing a card: the × in its corner (remove.js), shown on hover or focus */
.card { position: relative; }

.card-close {
  display: none;
  position: absolute;
  top: 8px;
  right: 8px;
  width: 22px;
  height: 22px;
  padding: 0;
  place-items: center;
  border: 0;
  border-radius: 50%;
  color: var(--muted);
  background: transparent;
  opacity: 0;
  cursor: pointer;
  transition: opacity 0.15s, color 0.15s, background-color 0.15s;
}

.can-remove .card-close { display: grid; }
.can-remove .card > h2 { padding-right: 26px; }
.card:hover .card-close,
.card:focus-within .card-close { opacity: 0.75; }
.card-close:hover,
.card-close:focus-visible { opacity: 1; color: var(--text); background: color-mix(in srgb, var(--text) 9%, transparent); }
.card-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.card-close svg { display: block; }
/* No hover on touch screens, so keep it faintly there. */
@media (hover: none) { .card-close { opacity: 0.45; } }
.is-reordering .card-close,
.card.is-lifted .card-close { opacity: 0; }

/* Asking before clearing everything (start-over.js) */
.start-over-list { margin: 0 0 12px; padding-left: 20px; display: grid; gap: 3px; font-size: 13px; color: var(--muted); }
.start-over-warning { margin: 0 0 4px; font-size: 13px; }
.customise .danger { color: #fff; background: var(--danger); border-color: var(--danger); font-weight: 600; }
.customise .danger:not(:disabled):hover { border-color: var(--danger); filter: brightness(1.08); }
.start-over .start-over-cancel { margin-left: auto; }

/* Asking before a card is removed */
.remove-dialog { width: min(440px, calc(100vw - 32px)); }
.remove-dialog h2 { margin-bottom: 12px; overflow-wrap: anywhere; }

.remove-preview {
  margin: 0 0 14px;
  padding: 10px 12px 8px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  font-size: 13px;
  /* Fades out at the bottom, like a card about to go. */
  mask-image: linear-gradient(to bottom, #000 60%, transparent);
}

.remove-preview strong { display: block; padding-bottom: 6px; margin-bottom: 6px; border-bottom: 1px solid var(--border); font-size: 14px; }
.remove-preview ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 5px; }
.remove-preview li,
.remove-preview p { margin: 0; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.remove-lead { margin: 0 0 8px; font-size: 13px; }

.remove-ways { display: grid; gap: 8px; margin: 0 0 16px; padding: 0; list-style: none; font-size: 13px; color: var(--muted); }
.remove-ways li { display: grid; grid-template-columns: 44px 1fr; align-items: start; gap: 10px; }
.remove-ways strong { color: var(--text); }

.remove-icon,
.remove-dialog kbd {
  display: grid;
  place-items: center;
  height: 24px;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  background: var(--surface);
  font: 600 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
}

.remove-dialog .primary { background: #b42318; border-color: #b42318; }

kbd {
  padding: 1px 5px;
  border: 1px solid var(--border);
  border-bottom-width: 2px;
  border-radius: 4px;
  background: var(--surface);
  font: 600 11px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;
  white-space: nowrap;
}

/* The undo message (undo.js) */
.undo-toast {
  inset: auto 0 20px;
  margin: 0 auto;
  display: none;
  align-items: center;
  gap: 4px;
  width: max-content;
  max-width: calc(100vw - 32px);
  padding: 6px 6px 6px 14px;
  border: 0;
  border-radius: 10px;
  color: var(--masthead-text);
  background: #1d1c1a;
  box-shadow: 0 12px 32px rgb(0 0 0 / 0.3);
  font-size: 13px;
  animation: toast-in 0.2s ease-out;
}

.undo-toast:popover-open { display: flex; }
.undo-toast.is-leaving { opacity: 0; transform: translateY(8px); transition: opacity 0.18s, transform 0.18s; }
.undo-toast-text { flex: 1; min-width: 0; margin-right: 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.undo-toast em { font-style: normal; color: #b5b0a6; }

.undo-toast button {
  flex: none;
  min-height: 28px;
  padding: 2px 10px;
  border: 0;
  border-radius: 6px;
  color: #f08a4b;
  background: transparent;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.undo-toast button:hover,
.undo-toast button:focus-visible { background: rgb(255 255 255 / 0.1); }
.undo-toast .undo-toast-close { width: 28px; padding: 0; color: #b5b0a6; font-size: 16px; font-weight: 400; }

@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } }

/* The History dialog (undo.js) */
.history-dialog .customise-head p { line-height: 1.5; }

.history-list {
  position: relative;
  max-height: min(420px, calc(100vh - 280px));
  margin: 0 0 6px;
  padding: 0;
  overflow-y: auto;
  list-style: none;
  scrollbar-width: thin;
}

.history-list li { position: relative; }

/* The timeline running down the left. */
.history-list li:not(.history-empty)::before {
  content: '';
  position: absolute;
  left: 15px;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--border);
}

.history-list li:first-child::before { top: 50%; }
.history-list li:last-child::before { bottom: 50%; }

.history-dialog .history-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 38px;
  padding: 6px 10px 6px 10px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  text-align: left;
}

.history-dialog .history-item:hover { border-color: var(--border); background: var(--surface); }
.history-dialog .is-current .history-item { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, var(--surface)); cursor: default; }

.history-dot {
  flex: none;
  width: 12px;
  height: 12px;
  border: 2px solid var(--muted);
  border-radius: 50%;
  background: var(--bg);
}

.is-current .history-dot { border-color: var(--accent); background: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent); }
.is-undone .history-dot { border-style: dashed; }
.is-undone .history-label { color: var(--muted); text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--muted) 60%, transparent); }

.history-label { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.history-item time { flex: none; color: var(--muted); font-size: 12px; }

.history-badge {
  flex: none;
  padding: 1px 6px;
  border-radius: 999px;
  color: var(--muted);
  background: color-mix(in srgb, var(--muted) 16%, transparent);
  font-size: 11px;
  font-weight: 600;
}

.is-current .history-badge { color: #fff; background: var(--accent); }
.history-empty { padding: 16px 4px; color: var(--muted); font-size: 13px; }

@media (prefers-reduced-motion: reduce) {
  .undo-toast { animation: none; }
  .card-close, .undo-toast.is-leaving { transition: none; }
}
.fog-icon { display: inline-block; vertical-align: -0.125em; }

/* The setup bar (setup-bar.js): between the masthead and the cards, a row of pillars that
   opens a drawer of choices (a sheet from the bottom on phones). Blue for choices, as in Settings. */

.setup-bar-wrap[hidden] { display: none; }

.setup-bar-wrap {
  --accent: var(--action);
  --sb-accent-text: #1d4ed8;
  --sb-field: rgb(255 255 255 / 0.55);
  --sb-field-hover: rgb(255 255 255 / 0.8);
  --sb-line: var(--border);
  padding-top: var(--gap);
}

@media (prefers-color-scheme: dark) {
  .setup-bar-wrap {
    --sb-accent-text: #93bbff;
    --sb-field: rgb(255 255 255 / 0.045);
    --sb-field-hover: rgb(255 255 255 / 0.09);
  }
}

/* The page fits the window (layout.js): the bar keeps its height and the grid takes the rest. */
body:has(.grid.packed) > .setup-bar-wrap { flex: none; }

/* Room kept for the bar before it's drawn (the early script in lib/render.js), so the cards don't jump. */
.setup-pending .setup-bar-wrap[hidden] { display: block; }
.setup-pending .setup-bar-wrap[hidden]::before {
  content: "";
  display: block;
  height: 56px;
  border: 1px solid var(--border);
  border-radius: calc(var(--card-radius) + 2px);
  background: var(--card-bg, var(--surface));
}
@media (max-width: 760px) { .setup-pending .setup-bar-wrap[hidden]::before { height: 106px; } }

.sb {
  position: relative;
  z-index: 12;
  border: 1px solid var(--sb-line);
  border-radius: calc(var(--card-radius) + 2px);
  color: var(--text);
  background:
    linear-gradient(90deg, color-mix(in srgb, var(--accent) 22%, transparent), transparent 380px),
    var(--card-bg, var(--surface));
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  backdrop-filter: blur(14px) saturate(1.3);
  box-shadow: 0 10px 30px -18px rgb(0 0 0 / 0.55);
  font-size: 13px;
}

.sb button { font: inherit; }

/* ---- compact row ------------------------------------------------------------------- */

.sb-main {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 56px;
  padding: 9px 10px 9px 14px;
}

.sb-intro { display: flex; flex: none; align-items: center; gap: 11px; }

.sb-spark {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  color: var(--sb-accent-text);
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent);
}

.sb-intro h2 { margin: 0; font-size: 14px; font-weight: 700; letter-spacing: -0.005em; white-space: nowrap; }
.sb-intro p { margin: 1px 0 0; color: var(--muted); font-size: 12px; white-space: nowrap; }

.sb-pillars {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  gap: 6px;
  min-width: 0;
  padding-left: 14px;
  border-left: 1px solid var(--sb-line);
  overflow-x: auto;
  scrollbar-width: none;
}

.sb-pillar {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 7px;
  height: 36px;
  padding: 0 9px 0 11px;
  border: 1px solid var(--sb-line);
  border-radius: 999px;
  color: var(--text);
  background: var(--sb-field);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.15s, border-color 0.15s;
}

.sb-pillar:hover { background: var(--sb-field-hover); border-color: color-mix(in srgb, var(--muted) 45%, transparent); }
.sb-pillar:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sb-pillar-icon { display: grid; color: var(--muted); }
.sb-pillar-icon svg, .sb-chevron svg { display: block; }
.sb-pillar-name { font-weight: 650; }
.sb-pillar-summary { max-width: 24ch; overflow: hidden; color: var(--muted); text-overflow: ellipsis; }
.sb-pillar.is-empty .sb-pillar-summary { color: var(--sb-accent-text); }
.sb-pillar-count {
  display: none;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  color: var(--sb-accent-text);
  background: color-mix(in srgb, var(--accent) 20%, transparent);
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}
.sb-chevron { display: grid; color: var(--muted); transition: transform 0.2s var(--ease-out); }

.sb-pillar[aria-expanded="true"] {
  border-color: color-mix(in srgb, var(--accent) 65%, transparent);
  background: color-mix(in srgb, var(--accent) 20%, transparent);
}
.sb-pillar[aria-expanded="true"] :is(.sb-pillar-icon, .sb-chevron) { color: var(--sb-accent-text); }
.sb-pillar[aria-expanded="true"] .sb-chevron { transform: rotate(180deg); }

.sb-pillar.is-quiet:not([aria-expanded="true"]) { border-color: transparent; background: transparent; }
.sb-pillar.is-quiet:not([aria-expanded="true"]):hover { background: var(--sb-field-hover); }
.sb-pillar.is-quiet .sb-pillar-name { font-weight: 550; }

.sb-divider { flex: none; width: 1px; height: 20px; margin: 0 2px; background: var(--sb-line); }

.sb-actions { display: flex; flex: none; align-items: center; gap: 4px; margin-left: auto; }

.sb-history {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 11px;
  border: 0;
  border-radius: 999px;
  color: var(--muted);
  background: none;
  white-space: nowrap;
  cursor: pointer;
}
.sb-history svg { display: block; flex: none; }
.sb-history:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sb-history:hover { color: var(--text); background: var(--sb-field-hover); }

.sb-advanced {
  padding: 8px 11px;
  border: 0;
  border-radius: 999px;
  color: var(--muted);
  background: none;
  white-space: nowrap;
  cursor: pointer;
}
.sb-advanced:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sb-advanced:hover { color: var(--text); background: var(--sb-field-hover); }

.sb-done {
  height: 34px;
  padding: 0 18px;
  border: 0;
  border-radius: 999px;
  color: #fff;
  background: var(--accent);
  font-weight: 650;
  cursor: pointer;
  box-shadow: 0 4px 14px -6px color-mix(in srgb, var(--accent) 80%, transparent);
}
.sb-done:hover { background: color-mix(in srgb, var(--accent) 86%, #000); }
.sb-done:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---- drawer -------------------------------------------------------------------------- */

.sb-drawer { border-top: 1px solid var(--sb-line); }
.sb-drawer[hidden] { display: none; }
.sb-sheet-head, .sb-sheet-foot { display: none; }

.sb-panel {
  display: grid;
  gap: 12px;
  padding: 14px 16px 13px;
  animation: sb-drawer-in 0.24s var(--ease-out);
}

@keyframes sb-drawer-in { from { opacity: 0; transform: translateY(-4px); } }

.sb-field { display: grid; grid-template-columns: 64px 1fr; align-items: start; gap: 12px; }
.sb-field-inline { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; }
.sb-field-inline .sb-label { width: 64px; padding-top: 0; }
.sb-field-inline .sb-label-gap { width: auto; margin-left: 22px; }

.sb-label {
  padding-top: 10px;
  color: var(--muted);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.sb .chips { gap: 7px; }
.sb .chip span { min-height: 32px; padding: 5px 13px 5px 10px; background: var(--sb-field); }
.sb .chip:hover span { background: var(--sb-field-hover); }
.sb .chip input:checked + span { color: var(--sb-accent-text); }
.sb .segmented { background: var(--sb-field); }
.sb .segmented span { padding: 5px 14px; }

.sb-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(236px, 1fr)); gap: 8px; }

.sb-tile {
  position: relative;
  display: grid;
  gap: 2px;
  min-width: 0;
  padding: 10px 40px 11px 13px;
  border: 1px solid var(--sb-line);
  border-radius: 11px;
  background: var(--sb-field);
  cursor: pointer;
  user-select: none;
  transition: background-color 0.15s, border-color 0.15s, transform 0.1s;
}
.sb-tile:hover { background: var(--sb-field-hover); border-color: color-mix(in srgb, var(--muted) 45%, transparent); }
.sb-tile:active { transform: scale(0.985); }
.sb-tile input { position: absolute; opacity: 0; pointer-events: none; }
.sb-tile-name { font-size: 14px; font-weight: 650; }
.sb-tile-sources {
  display: -webkit-box;
  overflow: hidden;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.35;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.sb-tile-check {
  position: absolute;
  top: 50%;
  right: 12px;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  margin-top: -10px;
  border: 1.5px solid color-mix(in srgb, var(--muted) 55%, transparent);
  border-radius: 50%;
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
}
.sb-tile-check::after { content: "+"; }

.sb-tile:has(input:checked) {
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
}
.sb-tile:has(input:checked) .sb-tile-check { border-color: var(--accent); color: #fff; background: var(--accent); font-size: 11px; }
.sb-tile:has(input:checked) .sb-tile-check::after { content: "✓"; }
.sb-tile:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

.sb-hint { margin: 0; color: var(--muted); font-size: 12px; }
.sb-warning { color: var(--warning); font-weight: 600; }
.sb-hint a, .sb-link { padding: 0; border: 0; color: var(--sb-accent-text); background: none; font: inherit; font-weight: 600; cursor: pointer; }
.sb-hint a:hover, .sb-link:hover { text-decoration: underline; }

.sb-switch { position: relative; display: inline-flex; align-items: center; gap: 9px; margin-right: 22px; cursor: pointer; }
.sb-switch input { position: absolute; opacity: 0; }
.sb-switch span {
  position: relative;
  width: 34px;
  height: 20px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--muted) 45%, transparent);
  transition: background-color 0.15s;
}
.sb-switch span::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.3);
  transition: transform 0.2s var(--ease-out);
}
.sb-switch input:checked + span { background: var(--accent); }
.sb-switch input:checked + span::after { transform: translateX(14px); }
.sb-switch input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---- the masthead's Customise button opens the bar (Settings is in it, as Advanced) ---- */

.customise-open[hidden] { display: none; }
.customise-open {
  display: inline-flex;
  flex: none;
  align-self: center;
  align-items: center;
  gap: 6px;
  height: 26px;
  margin-left: -4px;
  padding: 0 11px 0 9px;
  border: 1px solid var(--masthead-border);
  border-radius: 999px;
  color: var(--masthead-text);
  background: rgb(255 255 255 / 0.07);
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.15s, border-color 0.15s;
}
.customise-open svg { display: block; }
.customise-open:hover { background: rgb(255 255 255 / 0.14); }
.customise-open:focus-visible { outline: 2px solid var(--action); outline-offset: 2px; }
.customise-open.is-active {
  border-color: color-mix(in srgb, var(--action) 70%, transparent);
  background: color-mix(in srgb, var(--action) 32%, transparent);
}
.customise-open.sb-pulse { animation: sb-pulse 1.4s ease-out 2; }

@keyframes sb-pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--action) 70%, transparent); }
  100% { box-shadow: 0 0 0 10px transparent; }
}

/* ---- the page answering a change ------------------------------------------------------ */

.card.sb-new { animation: sb-new 2.6s var(--ease-out); }

@keyframes sb-new {
  0% { box-shadow: 0 0 0 0 transparent; }
  14%, 55% { box-shadow: 0 0 0 2px color-mix(in srgb, var(--action) 80%, transparent), 0 0 32px -6px var(--action); }
  100% { box-shadow: 0 0 0 0 transparent; }
}

.sb-empty-card .empty { margin: 12px 0; color: var(--muted); }

.sb-toast {
  position: fixed;
  right: 0;
  bottom: 22px;
  left: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 14px;
  width: max-content;
  max-width: calc(100vw - 32px);
  margin: 0 auto;
  padding: 8px 8px 8px 16px;
  border: 1px solid rgb(255 255 255 / 0.12);
  border-radius: 999px;
  color: #f4f2ee;
  background: rgb(20 20 19 / 0.9);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  box-shadow: 0 14px 34px -12px rgb(0 0 0 / 0.6);
  font-size: 13px;
}
.sb-toast[hidden] { display: none; }
.sb-toast > span { text-wrap: balance; }
@media (max-width: 760px) { .sb-toast { border-radius: 18px; } }
.sb-toast.is-in { animation: sb-toast-in 0.3s var(--ease-out); }
.sb-toast:not(:has(button)) { padding-right: 16px; }
.sb-undo {
  padding: 5px 13px;
  border: 0;
  border-radius: 999px;
  color: #fff;
  background: rgb(255 255 255 / 0.14);
  font: inherit;
  font-weight: 650;
  cursor: pointer;
}
.sb-undo:hover { background: rgb(255 255 255 / 0.24); }

@keyframes sb-toast-in { from { opacity: 0; transform: translateY(8px); } }

::view-transition-old(root),
::view-transition-new(root) { animation-duration: 0.22s; }

@media (prefers-reduced-motion: reduce) {
  .sb-panel, .sb-toast.is-in, .card.sb-new, .customise-open.sb-pulse { animation: none; }
}

/* ---- narrower windows ----------------------------------------------------------------- */

@media (max-width: 1520px) { .sb-intro p { display: none; } }

@media (max-width: 1340px) {
  .sb-pillar-summary { display: none; }
  .sb-pillar-count { display: inline-block; }
}

@media (max-width: 1000px) {
  .sb-intro-text { display: none; }
  .sb-advanced { display: none; }
  .sb-history span { display: none; }
  .sb-history { padding: 8px; }
}

/* Phones: the pillars scroll sideways under the title, and a drawer is a sheet from the bottom. */
@media (max-width: 760px) {
  .sb-main { flex-wrap: wrap; gap: 10px; padding: 12px 12px 10px; }
  .sb-intro { flex: 1; }
  .sb-intro-text { display: block; }
  .sb-intro p { display: block; white-space: normal; }
  .sb-actions { margin-left: 0; }
  .sb-pillars {
    flex-basis: 100%;
    order: 3;
    margin: 0 -12px;
    padding: 2px 12px;
    border-left: 0;
    -webkit-mask-image: linear-gradient(90deg, #000 85%, transparent);
    mask-image: linear-gradient(90deg, #000 85%, transparent);
  }
  .sb-pillar-summary { display: none; }
  .sb-pillar-count { display: inline-block; }

  .sb-drawer {
    position: fixed;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 55;
    max-height: 80dvh;
    overflow-y: auto;
    padding: 0 16px;
    border: 1px solid var(--sb-line);
    border-bottom: 0;
    border-radius: 18px 18px 0 0;
    background: var(--bg);
    box-shadow: 0 -18px 50px -10px rgb(0 0 0 / 0.5);
    animation: sb-sheet-in 0.3s var(--ease-out);
  }
  .sb-sheet-head {
    position: sticky;
    top: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 0 6px;
    background: var(--bg);
  }
  .sb-sheet-head h3 { margin: 0; font-size: 18px; }
  .sb-sheet-close {
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border: 0;
    border-radius: 50%;
    color: var(--muted);
    background: var(--sb-field-hover);
  }
  .sb-panel { padding: 8px 0 16px; animation: none; }
  .sb-field { grid-template-columns: 1fr; gap: 8px; }
  .sb-label { padding-top: 0; }
  .sb-field-inline .sb-label-gap { margin-left: 0; }
  .sb-field-inline .sb-label { width: 100%; }
  .sb-tiles { grid-template-columns: 1fr; }
  .sb-sheet-foot {
    position: sticky;
    bottom: 0;
    display: block;
    padding: 10px 0 calc(14px + env(safe-area-inset-bottom));
    background: var(--bg);
  }
  .sb-sheet-foot .sb-done { width: 100%; height: 46px; font-size: 15px; }

  /* A blurred ancestor would trap the fixed sheet inside it, and the bar must sit above the dimming. */
  html.sb-sheet-open .sb { z-index: 56; -webkit-backdrop-filter: none; backdrop-filter: none; }

  html.sb-sheet-open body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 50;
    background: rgb(0 0 0 / 0.45);
  }
  .sb-toast { bottom: 16px; }
  html.sb-sheet-open .sb-toast { bottom: auto; top: 16px; }
}

@keyframes sb-sheet-in { from { transform: translateY(100%); } }
