/* Palette: only the sky (--bg-a/--bg-b) and ink colours change per theme; glass
   layers and data colours come from two token sets (light skies / dark skies).
   Every text/background pair was checked against WCAG (body text ≥ 6:1, dim
   text ≥ 4.6:1 on every surface). Coloured text (--precip, --accent-ink) is
   only legible on cards, tiles and chips: never place it directly on the sky. */

@property --bg-a { syntax: '<color>'; inherits: true; initial-value: #4fb3ff; }
@property --bg-b { syntax: '<color>'; inherits: true; initial-value: #b3e2ff; }

/* Light skies (day, dawn, golden hour, hot day). */
:root {
  --radius: 22px;
  --text: #0a2540;
  --text-dim: #223c5c;
  --card: rgba(255, 255, 255, 0.5);
  --card-border: rgba(255, 255, 255, 0.8);
  --card-shadow: 0 4px 16px rgba(10, 37, 64, 0.08);
  --tile: rgba(255, 255, 255, 0.5);
  --chip: rgba(255, 255, 255, 0.6);
  --chip-active: #ffffff;
  --chip-active-border: rgba(255, 255, 255, 0.8);
  --menu: #ffffff;
  --hover: rgba(10, 37, 64, 0.07);
  --track: rgba(10, 37, 64, 0.12);
  --divider: rgba(10, 37, 64, 0.12);
  --bar-outline: rgba(10, 37, 64, 0.18);
  --button-bg: #1d4ed8;
  --button-text: #ffffff;
  --banner: #ffffff;
  --star: #ffb020;
  --accent-ink: #8a4200;
  --precip: #1455b3;
  --danger: #b3261e;
  --bg-a: #4fb3ff;
  --bg-b: #b3e2ff;
  color-scheme: light;
  font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Noto Sans Hebrew', 'Noto Sans', Arial, sans-serif;
  -webkit-tap-highlight-color: transparent;
}

/* Dark skies (night, twilight): dark glass, never white-tinted surfaces. */
:root[data-mode='dark'] {
  --text: #ffffff;
  --text-dim: #d3def7;
  --card: rgba(8, 14, 38, 0.28);
  --card-border: rgba(255, 255, 255, 0.14);
  --card-shadow: none;
  --tile: rgba(255, 255, 255, 0.07);
  --chip: rgba(8, 14, 38, 0.28);
  --chip-active: rgba(8, 14, 38, 0.4);
  --chip-active-border: #ffffff;
  --menu: #1b2750;
  --hover: rgba(255, 255, 255, 0.1);
  --track: rgba(255, 255, 255, 0.2);
  --divider: rgba(255, 255, 255, 0.14);
  --bar-outline: rgba(255, 255, 255, 0.22);
  --button-bg: #ffffff;
  --button-text: #1e3a8a;
  --banner: rgba(8, 14, 38, 0.6);
  --accent-ink: #ffc94d;
  --precip: #a6d4ff;
  --danger: #ffb4ab;
  color-scheme: dark;
}

/* Sky per condition and time of day; set by insights.js skyTheme(). */
:root[data-theme='clear-day'] { --bg-a: #4fb3ff; --bg-b: #b3e2ff; --text: #0a2540; --text-dim: #223c5c; }
:root[data-theme='cloudy-day'] { --bg-a: #95b8e0; --bg-b: #e0ebf8; --text: #0f2744; --text-dim: #2b4461; }
:root[data-theme='rain-day'] { --bg-a: #82afd9; --bg-b: #d2e5f4; --text: #0a2540; --text-dim: #263e5a; }
:root[data-theme='snow-day'] { --bg-a: #a6d4fb; --bg-b: #f0f8ff; --text: #0d2a4a; --text-dim: #37567a; }
:root[data-theme='storm-day'] { --bg-a: #aaa6ea; --bg-b: #e2e0f8; --text: #17123d; --text-dim: #39346e; }
:root[data-theme='fog-day'] { --bg-a: #b7c6d8; --bg-b: #f0f3f7; --text: #14283f; --text-dim: #3a4f67; }
:root[data-theme='hot-day'] { --bg-a: #ffb257; --bg-b: #ffe6c9; --text: #351703; --text-dim: #6e3c14; }
:root[data-theme='dawn'] { --bg-a: #8fb8f2; --bg-b: #ffd4b0; --text: #1e1b3f; --text-dim: #3e3a66; }
:root[data-theme='golden-hour'] { --bg-a: #86b2f0; --bg-b: #ffc47f; --text: #22193a; --text-dim: #3f325a; }
:root[data-theme='clear-night'] { --bg-a: #2f57c0; --bg-b: #23397b; }
:root[data-theme='cloudy-night'] { --bg-a: #3f5687; --bg-b: #303e5d; }
:root[data-theme='rain-night'] { --bg-a: #22608a; --bg-b: #243e59; }
:root[data-theme='snow-night'] { --bg-a: #3d62a6; --bg-b: #32477a; --text-dim: #dae3f8; }
:root[data-theme='storm-night'] { --bg-a: #4d38a0; --bg-b: #2e2766; }
:root[data-theme='fog-night'] { --bg-a: #4b5a70; --bg-b: #364050; }
:root[data-theme='twilight'] { --bg-a: #28327f; --bg-b: #8a3d6e; --text-dim: #f0dcec; }

/* Sunlight / high-contrast mode: near-opaque surfaces. */
@media (prefers-contrast: more) {
  :root:not([data-mode='dark']) { --card: rgba(255, 255, 255, 0.85); --tile: rgba(255, 255, 255, 0.7); --chip: rgba(255, 255, 255, 0.85); }
  :root[data-mode='dark'] { --card: rgba(8, 14, 38, 0.6); --tile: rgba(255, 255, 255, 0.1); --chip: rgba(8, 14, 38, 0.6); }
}

* { box-sizing: border-box; }

[hidden] { display: none !important; }

html { background: var(--bg-b); }

body {
  margin: 0;
  min-height: 100dvh;
  color: var(--text);
  background: linear-gradient(170deg, var(--bg-a), var(--bg-b)) fixed;
  background: linear-gradient(170deg in oklab, var(--bg-a), var(--bg-b)) fixed;
  transition: --bg-a 1s ease-in-out, --bg-b 1s ease-in-out;
  font-variant-numeric: tabular-nums;
  line-height: 1.4;
}

.wrap {
  max-width: 680px;
  margin: 0 auto;
  padding: calc(12px + env(safe-area-inset-top)) 16px calc(24px + env(safe-area-inset-bottom));
}

h1, h2, p { margin: 0; }

button {
  font: inherit;
  color: inherit;
  cursor: pointer;
}

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 2px;
}

svg { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* ---------- top bar & search ---------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  gap: 8px;
  margin: 0 -16px;
  padding: 8px 16px 14px;
  /* body's background is fixed, so --bg-a is what sits behind the bar */
  background: linear-gradient(to bottom, var(--bg-a) 70%, transparent);
}

/* Tablets and landscape (Android 16 ignores the portrait lock there): the
   bar's sky fade spans the whole window rather than ending at the page's
   edges. The outset only paints; it never scrolls. */
@media (min-width: 720px) {
  .topbar {
    background: none;
    border-image: linear-gradient(to bottom, var(--bg-a) 70%, transparent) fill 0 / / 0 100vw;
  }
}

.search {
  position: relative;
  flex: 1;
  min-width: 0;
}

.search-icon {
  position: absolute;
  inset-inline-start: 13px;
  top: 50%;
  z-index: 1;
  width: 18px;
  height: 18px;
  transform: translateY(-50%);
  opacity: 0.8;
  pointer-events: none;
}

#search {
  width: 100%;
  min-width: 0;
  height: 46px;
  padding-inline: 40px 12px;
  /* Between the menu and location buttons a 360 px phone leaves ~165 px of text. */
  text-overflow: ellipsis;
  border: 1px solid var(--card-border);
  border-radius: 999px;
  background: var(--card);
  box-shadow: var(--card-shadow);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  color: var(--text);
  font: inherit;
  font-size: 16px; /* prevents zoom-on-focus on mobile */
}

#search::placeholder { color: var(--text-dim); text-overflow: ellipsis; }
:root[data-mode='dark'] #search::-webkit-search-cancel-button { filter: invert(1); }

.results {
  position: absolute;
  inset-inline: 0;
  top: calc(100% + 6px);
  margin: 0;
  padding: 6px;
  list-style: none;
  border-radius: 16px;
  background: var(--menu);
  box-shadow: 0 16px 40px rgba(10, 37, 64, 0.25);
  max-height: 60vh;
  overflow-y: auto;
}

.result {
  display: flex;
  flex-direction: column;
  padding: 10px 12px;
  border-radius: 10px;
  cursor: pointer;
}

.result:hover, .result.active { background: var(--hover); }
.result.active { outline: 2px solid var(--text); outline-offset: -2px; }
.result.empty { color: var(--text-dim); cursor: default; }
.r-name { font-weight: 600; }
.r-sub { font-size: 13px; color: var(--text-dim); }

.icon-btn {
  flex: none;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border: 1px solid var(--card-border);
  border-radius: 50%;
  background: var(--card);
  box-shadow: var(--card-shadow);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}

.icon-btn svg { width: 22px; height: 22px; }
.icon-btn.busy svg { animation: pulse 1s ease-in-out infinite; }

@keyframes pulse { 50% { opacity: 0.3; transform: scale(0.85); } }

/* ---------- chips ---------- */

.chips, .chip-row {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scrollbar-width: none;
}

.chips { padding: 4px 0 12px; }
.chip-row { flex-wrap: wrap; justify-content: center; }
.chips::-webkit-scrollbar { display: none; }

.chip {
  flex: none;
  padding: 7px 14px;
  border: 1px solid var(--card-border);
  border-radius: 999px;
  background: var(--chip);
  font-size: 14px;
  white-space: nowrap;
}

.chip.active {
  padding: 6px 13px;
  border: 2px solid var(--chip-active-border);
  background: var(--chip-active);
  font-weight: 600;
}

/* ---------- cards ---------- */

/* minmax(0, 1fr): the scrolling hourly strip must not widen the column. */
main { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; }
main[aria-busy='true'] { opacity: 0.85; }

.card {
  padding: 18px;
  border: 1px solid var(--card-border);
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: var(--card-shadow);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}

.card h2 {
  margin-bottom: 12px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text-dim);
}

.banner {
  padding: 10px 14px;
  border-radius: 14px;
  border-inline-start: 6px solid #ffb020;
  background: var(--banner);
  font-size: 14px;
}

/* The one rating request (app.js rateHtml): a short line and two buttons. */
.rate-card {
  display: grid;
  gap: 12px;
  padding: 14px 18px;
  font-size: 15px;
}

.rate-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

.rate-actions .pill-btn,
.rate-actions .text-btn { min-height: 44px; }

.message {
  display: grid;
  justify-items: center;
  gap: 14px;
  padding: 40px 18px;
  text-align: center;
}

.spinner {
  width: 32px;
  height: 32px;
  border: 3px solid var(--track);
  border-top-color: var(--text);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

.pill-btn {
  padding: 11px 22px;
  border: 0;
  border-radius: 999px;
  background: var(--button-bg);
  color: var(--button-text);
  font-weight: 600;
}

/* ---------- welcome ---------- */

.welcome {
  display: grid;
  justify-items: center;
  gap: 12px;
  padding: 32px 20px;
  text-align: center;
}

.welcome-logo { border-radius: 18px; }
.welcome h1 { font-size: 24px; }
.welcome p { color: var(--text-dim); }
.welcome h2 { margin: 12px 0 0; }

/* ---------- current conditions ---------- */

.place-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
}

.place-name {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 24px;
  font-weight: 700;
}

.gps-mark { width: 16px; height: 16px; fill: currentColor; stroke: none; opacity: 0.85; }
.place-sub { margin-top: 2px; font-size: 14px; color: var(--text-dim); }
.nowrap { white-space: nowrap; }

.fav-btn {
  flex: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: transparent;
}

.fav-btn svg { width: 24px; height: 24px; }
.fav-btn[aria-pressed='true'] svg { fill: var(--star); stroke: var(--text); stroke-width: 1.5; }

.now {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 8px;
}

.now-icon { width: 108px; height: 108px; }

.now-temp {
  font-size: 84px;
  font-weight: 200;
  line-height: 1;
  letter-spacing: -0.03em;
}

.now-desc { text-align: center; font-size: 18px; font-weight: 600; }
.now-range { margin-top: 2px; text-align: center; color: var(--text-dim); }

/* "Feels like" is a button with a small "i": a tap opens one line on what it means. */
.feels-btn {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin: -6px 0;
  padding: 6px 2px;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
}
.info-icon { width: 1.05em; height: 1.05em; stroke-width: 2; opacity: 0.85; }
.feels-btn[aria-expanded='true'] .info-icon { opacity: 1; }
.feels-hint {
  max-width: 30em;
  margin: 6px auto 0;
  padding: 6px 12px;
  border-radius: 12px;
  background: var(--tile);
  font-size: 14px;
  text-align: center;
}

/* Read by screen readers only ("low", "high" before the day's temperatures). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.heat-chip {
  display: table;
  margin: 10px auto 0;
  padding: 4px 12px;
  border-radius: 10px;
  border-inline-start: 5px solid;
  background: var(--tile);
  font-size: 14px;
  font-weight: 600;
}

.heat-1 { border-color: #f7d23a; }
.heat-2 { border-color: #fca235; }
.heat-3 { border-color: #f4652e; }
.heat-4 { border-color: #d92f4f; }
.heat-5 { border-color: #a8227f; }

.summary {
  display: grid;
  gap: 6px;
  margin: 14px 0 0;
  padding: 12px 14px;
  list-style: none;
  border-radius: 16px;
  background: var(--tile);
  font-size: 15px;
  line-height: 1.35;
}

.summary li { display: flex; gap: 8px; }
.summary li span { flex: none; }

.radar-link {
  display: inline-block;
  margin-top: 10px;
  font-size: 14px;
  font-weight: 600;
}

/* Two tiles a row on a phone, three where there is room; one when the text is
   very large (the minimum is in rem, so it grows with the font). */
.details {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(max(8.5rem, 30%), 100%), 1fr));
  gap: 10px;
  margin: 0;
}

.details div {
  padding: 10px 12px;
  border-radius: 14px;
  background: var(--tile);
}

.details dt { font-size: 12px; color: var(--text-dim); }
.details dd { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 2px 0 0; font-weight: 600; }
.details small { width: 100%; font-weight: 400; font-size: 13px; color: var(--text-dim); }
.wind-arrow { width: 16px; height: 16px; fill: currentColor; stroke: none; }

.uv-pill { padding: 1px 9px; border-radius: 999px; font-weight: 700; }
.uv-0 { background: #43b649; color: #0b2a0e; }
.uv-1 { background: #f7d51d; color: #2a2100; }
.uv-2 { background: #f7862a; color: #2a1400; }
.uv-3 { background: #d92b3a; color: #ffffff; }
.uv-4 { background: #7b4fd6; color: #ffffff; }

.stamp { margin-top: 12px; font-size: 12px; color: var(--text-dim); text-align: center; }

/* ---------- hourly ---------- */

.hourly {
  display: flex;
  gap: 4px;
  margin: 0 -8px;
  padding: 0 0 4px;
  list-style: none;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
  scrollbar-color: var(--track) transparent;
}

.hour {
  position: relative;
  flex: none;
  display: grid;
  justify-items: center;
  gap: 4px;
  width: 60px;
  scroll-snap-align: start;
}

.hour-button {
  display: grid;
  justify-items: center;
  gap: 4px;
  width: 100%;
  min-height: 44px;
  padding: 4px 0;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.hour-button:hover { background: var(--hover); }
.hour-button:focus-visible { outline: 2px solid var(--text); outline-offset: -2px; }
.hour-hint, .hour-zone, .hour-note { color: var(--text-dim); font-size: 13px; }
.hour-sheet .icon-btn.small { min-width: 44px; min-height: 44px; }
.hour-sheet .sheet-head h2 { min-width: 0; overflow-wrap: anywhere; }
.hour-sheet .hour-place { font-weight: 600; }
.hour-when, .hour-zone, .hour-details, .hour-note { overflow-wrap: anywhere; }
.hour-details { display: grid; gap: 12px; margin: 18px 0; }
/* Font-relative bases let enlarged labels and values use separate lines. */
.hour-details > div { display: flex; flex-wrap: wrap; gap: 4px 12px; }
.hour-details dt { flex: 1 1 8ch; min-width: 0; max-width: 100%; color: var(--text-dim); }
.hour-details dd { flex: 1.4 1 12ch; min-width: 0; max-width: 100%; margin: 0; font-weight: 600; }
.hour-details small { display: block; margin-top: 4px; font-weight: 400; }


/* The first hour of a new day: its name above, starting at a thin line in the
   gap before it (the chart continues the line, meteogram.js .mg-day). */
.h-day {
  justify-self: start;
  min-height: 1.3em;
  padding-inline-start: 4px;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.3;
  white-space: nowrap;
}
.h-newday::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  inset-inline-start: -2.5px;
  border-inline-start: 1px dashed var(--text-dim);
  opacity: 0.6;
}

.h-time { font-size: 13px; color: var(--text-dim); }
.h-icon { width: 36px; height: 36px; }
.h-temp { position: relative; padding-bottom: 6px; font-weight: 600; }
.h-temp::after {
  content: '';
  position: absolute;
  inset-inline: 10%;
  bottom: 0;
  height: 3px;
  border-radius: 2px;
  background: var(--tc);
}
.h-precip { min-height: 16px; font-size: 11px; color: var(--precip); white-space: nowrap; }

/* ---------- daily ---------- */

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

/* Each day is a button that opens its hours. Fixed widths (in rem, so they
   grow with the font) keep the columns aligned from row to row; when a row
   is too narrow (very large text, or a phone's zoom) the temperatures move
   to a second line instead of running off the screen. */
.day {
  --dn: 4.6rem;
  --dp: 3.6rem;
  --dt: 2.6rem;
  --dg: 8px;
}

.d-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px var(--dg);
  width: 100%;
  padding: 8px 0;
  border: 0;
  border-radius: 10px;
  background: none;
  color: inherit;
  font: inherit;
  text-align: start;
}

@media (hover: hover) {
  .d-row:hover { background: var(--hover); }
}

.d-row > * { min-width: 0; }
.d-name { flex: 0 0 var(--dn); }
.d-row > .d-icon { flex: none; }
.d-precip { flex: 0 0 var(--dp); }
.d-temps {
  flex: 1 1 calc(2 * var(--dt) + 4rem);
  display: flex;
  align-items: center;
  gap: var(--dg);
}
.d-min, .d-max { flex: 0 0 var(--dt); }
.d-temps .d-bar { flex: 1 1 auto; min-width: 1.5rem; }

/* Chevron: down when closed, up when open. */
.d-chev {
  flex: none;
  width: 8px;
  height: 8px;
  margin-inline: 2px 4px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  opacity: 0.55;
  transform: translateY(-2px) rotate(45deg);
  transition: transform 0.2s;
}
.day.open .d-chev { transform: translateY(2px) rotate(-135deg); }

.day + .day { border-top: 1px solid var(--divider); }

/* An opened day: its hours scroll sideways; its four parts share the row. */
.d-more { padding: 2px 0 10px; }
.d-hours {
  display: flex;
  gap: 4px;
  margin: 0;
  padding: 8px 2px 6px;
  list-style: none;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
  scrollbar-color: var(--track) transparent;
  border-radius: 14px;
  background: var(--tile);
}
.d-parts { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(4.2rem, 100%), 1fr)); row-gap: 10px; overflow: visible; }

.dh {
  flex: none;
  display: grid;
  justify-items: center;
  align-content: start;
  gap: 2px;
  min-width: 3.4rem;
  padding: 0 2px;
  scroll-snap-align: start;
  text-align: center;
}
.d-parts .dh { min-width: 0; }
.dh-time { font-size: 13px; font-weight: 600; }
.dh-part .dh-time { overflow-wrap: break-word; }
.dh-span { font-size: 11px; color: var(--text-dim); }
.dh-icon { width: 32px; height: 32px; }
.dh-temp { font-weight: 600; }
.dh-low { font-size: 13px; color: var(--text-dim); }
.dh-precip { min-height: 1.2em; font-size: 11px; color: var(--precip); white-space: nowrap; }
.dh-wind { display: grid; justify-items: center; font-size: 13px; line-height: 1.2; }
.dh-wind small { font-size: 10px; color: var(--text-dim); }
.dh-arrow { width: 14px; height: 14px; fill: currentColor; stroke: none; }


.d-sep {
  padding: 12px 0 6px;
  border-top: 1px dashed var(--divider);
  font-size: 12px;
  color: var(--text-dim);
}

.d-name { display: grid; font-weight: 600; }
.d-name small { font-weight: 400; font-size: 12px; color: var(--text-dim); }
.d-icon { width: 36px; height: 36px; }
.d-precip { font-size: 12px; color: var(--precip); white-space: nowrap; }
.d-min { color: var(--text-dim); text-align: end; }
.d-max { font-weight: 600; }

.d-bar {
  position: relative;
  height: 8px;
  border-radius: 4px;
  background: var(--track);
}

.d-bar span {
  position: absolute;
  top: 0;
  bottom: 0;
  border-radius: 4px;
  box-shadow: inset 0 0 0 1px var(--bar-outline);
}

/* "Now" marker: ink dot in a white ring, legible on every scale colour. */
.d-now {
  position: absolute;
  top: 50%;
  width: 10px;
  height: 10px;
  margin-top: -5px;
  margin-inline-start: -5px;
  border-radius: 50%;
  background: #0a2540;
  box-shadow: 0 0 0 2px #ffffff;
}

/* Phones: tighter fixed columns so the range bar keeps a useful width. */
@media (max-width: 430px) {
  .day { --dn: 3.3rem; --dp: 2.8rem; --dt: 2.1rem; --dg: 5px; font-size: 14px; }
  .d-icon { width: 32px; height: 32px; }
  .d-precip { font-size: 11px; }
}

/* ---------- sun & moon ---------- */

.sun-arc { display: block; width: 100%; max-width: 280px; height: auto; margin: 0 auto; }
.sun-arc .horizon { stroke: var(--divider); stroke-width: 1.5; }
.sun-arc .arc { stroke: var(--text-dim); stroke-width: 1.5; stroke-dasharray: 4 5; opacity: 0.7; }
.sun-arc .sun { fill: #ffb020; stroke: var(--text); stroke-width: 1.5; }

.sun-times {
  display: grid;
  /* Three across; fewer when the text is very large or the screen very narrow. */
  grid-template-columns: repeat(auto-fit, minmax(min(5.5rem, 100%), 1fr));
  gap: 8px;
  margin-top: 6px;
  text-align: center;
}

.sun-times span { display: block; font-size: 12px; color: var(--text-dim); }
.sun-times b { font-size: 17px; }
.sun-times small { display: block; font-size: 11px; color: var(--text-dim); }
.sun-extra { margin-top: 12px; text-align: center; font-size: 14px; color: var(--text-dim); }
.sun-polar { text-align: center; font-weight: 600; }

/* ---------- footer: the data credit line only ---------- */

.footer {
  margin-top: 20px;
  padding: 0 8px;
  text-align: center;
}

.credit { font-size: 12px; line-height: 1.6; color: var(--text-dim); }
.credit a { color: inherit; }
/* One source per piece: a line breaks between them, not inside "(CC BY 4.0)". */
.credit span { display: inline-block; }

.text-btn {
  padding: 7px 14px;
  border: 1px solid var(--card-border);
  border-radius: 999px;
  background: var(--chip);
  font-size: 14px;
}

/* ---------- menu (top bar, inline start) ---------- */

/* A modal <dialog> dropped from its button; app.js sets --menu-top and
   --menu-start from the button's place (menu.js menuPlacement). */
.menu {
  position: fixed;
  inset: auto;
  top: var(--menu-top, 64px);
  inset-inline-start: var(--menu-start, 16px);
  width: max-content;
  min-width: 224px;
  max-width: min(320px, calc(100vw - 32px));
  max-height: calc(100dvh - var(--menu-top, 64px) - 16px);
  margin: 0;
  padding: 6px;
  overflow-y: auto;
  border: 1px solid var(--card-border);
  border-radius: 18px;
  background: var(--menu);
  color: var(--text);
  box-shadow: 0 12px 36px rgba(10, 37, 64, 0.28);
  transform-origin: top left;
}

:root[dir='rtl'] .menu { transform-origin: top right; }
.menu[open] { animation: menu-in 0.14s ease-out; }
.menu::backdrop { background: rgba(10, 20, 40, 0.16); }

@keyframes menu-in { from { opacity: 0; transform: scale(0.96); } }

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

/* 48 px rows: a finger's width, as on Android's own menus. */
.menu-item {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  min-height: 48px;
  padding: 10px 14px;
  border: 0;
  border-radius: 12px;
  background: none;
  color: inherit;
  font: inherit;
  font-size: 16px;
  line-height: 1.3;
  text-align: start;
  text-decoration: none;
}

.menu-item svg { flex: none; width: 22px; height: 22px; opacity: 0.8; }
.menu-item:focus-visible { outline: 2px solid var(--text); outline-offset: -2px; }
.menu-item:active { background: var(--hover); }

@media (hover: hover) {
  .menu-item:hover { background: var(--hover); }
}

.toast {
  position: fixed;
  inset-inline: 16px;
  bottom: calc(20px + env(safe-area-inset-bottom));
  z-index: 20;
  max-width: 480px;
  margin: 0 auto;
  padding: 12px 16px;
  border-radius: 14px;
  background: var(--menu);
  color: var(--text);
  box-shadow: 0 10px 30px rgba(10, 37, 64, 0.3);
  text-align: center;
}

@media (prefers-reduced-motion: reduce) {
  body { transition: none; }
  .spinner, .icon-btn.busy svg { animation-duration: 3s; }
  .menu[open] { animation: none; }
}

/* ---------- clothing hints ---------- */

.hints {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}

.hints span {
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--tile);
  font-size: 13px;
  font-weight: 600;
}

/* ---------- dialogs (about, settings) ---------- */

.link-btn {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  text-decoration: underline;
}

.sheet {
  width: min(560px, calc(100vw - 32px));
  max-height: calc(100dvh - 48px);
  padding: 18px;
  border: 1px solid var(--card-border);
  border-radius: var(--radius);
  background: var(--menu);
  color: var(--text);
  box-shadow: 0 20px 50px rgba(10, 37, 64, 0.35);
}

.sheet::backdrop { background: rgba(10, 20, 40, 0.45); }

.sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}

.sheet h2 { font-size: 20px; }
.sheet h3 { margin: 16px 0 6px; font-size: 15px; }
.sheet p { margin: 0 0 8px; line-height: 1.5; }

.icon-btn.small {
  width: 36px;
  height: 36px;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  background: var(--hover);
}

.icon-btn.small svg { width: 18px; height: 18px; }
.icon-btn:disabled { opacity: 0.35; cursor: default; }

.credits { margin: 0; padding-inline-start: 18px; }
.credits li { margin-bottom: 6px; }
.credits small, .setting-hint, .about-links { color: var(--text-dim); font-size: 13px; }

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

.layout-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 0;
  border-top: 1px solid var(--divider);
}

.layout-list label { display: flex; align-items: center; gap: 8px; }
.layout-list input { width: 18px; height: 18px; accent-color: var(--button-bg); }
.layout-list span { display: flex; gap: 6px; }

/* ================= meteogram ================= */
/* ---------- hourly meteogram ---------- */

/* Card header: title plus the chart toggle; the toggle wraps under the title on narrow phones. */
.mg-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
  margin-bottom: 12px;
}

.card .mg-head h2 { margin: 0; }

/* Segmented control: a track with the selected option raised as a chip. */
.mg-toggle {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  background: var(--track);
}

.mg-toggle button {
  min-height: 30px;
  padding: 4px 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font-size: 13px;
  white-space: nowrap;
}

@media (hover: hover) {
  .mg-toggle button:hover { background: var(--hover); }
}

.mg-toggle button[aria-pressed='true'] {
  background: var(--chip-active);
  box-shadow: 0 0 0 1px var(--chip-active-border), var(--card-shadow);
  font-weight: 600;
}

/* The chart is the strip's last item, pinned under the hour items so it
   scrolls with them; inline-start keeps hour 0 above column 0 in RTL too. */
.hourly.mg-host {
  position: relative;
  padding-bottom: 92px;
}

.mg-row {
  position: absolute;
  inset-inline-start: 0;
  bottom: 4px;
  height: 80px;
  pointer-events: none;
}

.mg { display: block; overflow: visible; font-size: 11px; }
/* The global svg rule strokes everything; text must be fill-only. */
.mg text { stroke: none; }
.mg-label { fill: var(--text); font-weight: 600; }
.mg-note { fill: var(--text-dim); font-size: 13px; }
.mg-base { stroke: var(--divider); stroke-width: 1; }
.mg-day { stroke: var(--text-dim); stroke-width: 1; stroke-dasharray: 3 3; opacity: 0.6; }
/* Temperature: the stroke itself is the scale gradient (set in the markup). */
.mg-case { stroke: var(--bar-outline); stroke-width: 4; }
.mg-feels, .mg-gust { stroke: var(--text-dim); stroke-width: 1.5; stroke-dasharray: 3 4; }
.mg-bar { fill: var(--precip); stroke: none; }
.mg-possible { fill: none; stroke: var(--precip); stroke-width: 1.5; stroke-dasharray: 3 2; }
.mg-wind { stroke: var(--text); }
.mg-arrow { fill: var(--text-dim); stroke: none; }

.mg-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin-top: 8px;
  font-size: 12px;
  color: var(--text-dim);
}

.mg-legend:empty { display: none; }
.forecast-note { margin: 12px 0 0; color: var(--text-dim); font-size: 12px; line-height: 1.5; }
.mg-key { display: inline-flex; align-items: center; gap: 6px; }
.mg-key i { width: 18px; border-top: 2px solid var(--text); }
.mg-key-temp i { height: 3px; border: 0; border-radius: 2px; background: var(--text); }
.mg-key-feels i, .mg-key-gust i { border-top-style: dashed; border-color: var(--text-dim); }
.mg-key-bar i, .mg-key-possible i { width: 10px; height: 10px; border: 0; border-radius: 2px 2px 0 0; background: var(--precip); }
.mg-key-possible i { border: 1.5px dashed var(--precip); border-radius: 2px; background: none; }
.mg-key svg { width: 12px; height: 12px; fill: var(--text-dim); stroke: none; }

/* ================= jewish ================= */
/* ---------- Shabbat & holidays ---------- */

.jw-date { margin-bottom: 12px; text-align: center; font-size: 18px; font-weight: 600; }

.jw-times { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(7rem, 100%), 1fr)); gap: 8px; text-align: center; }
.jw-times > div { padding: 8px 6px; border-radius: 14px; background: var(--tile); }
.jw-times span { display: block; font-size: 12px; color: var(--text-dim); }
.jw-times b { font-size: 17px; }

.jw-greeting { margin-top: 10px; text-align: center; font-weight: 600; }
.jw-note { margin-top: 8px; text-align: center; font-size: 12px; color: var(--text-dim); }

.jw-holidays { margin: 12px 0 0; padding: 0; list-style: none; font-size: 14px; }
.jw-holidays li { display: flex; justify-content: space-between; gap: 12px; padding: 7px 0; border-top: 1px solid var(--divider); }
.jw-holidays span { flex: none; color: var(--text-dim); }
.jw-holidays b { font-weight: 600; text-align: end; }
.jw-holidays .is-today b { color: var(--accent-ink); }

/* ================= share ================= */
/* ---------- share ---------- */

/* Share and favourite sit together at the inline end of the place row. */
.place-actions { flex: none; display: flex; gap: 2px; }

/* Same footprint as .fav-btn. */
.share-btn {
  flex: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: transparent;
}

.share-btn svg { width: 22px; height: 22px; }
.share-btn:disabled { cursor: progress; }
.share-btn[aria-busy='true'] svg { animation: pulse 1s ease-in-out infinite; }

@media (prefers-reduced-motion: reduce) {
  .share-btn[aria-busy='true'] svg { animation-duration: 3s; }
}

/* ================= sky ================= */
/* ---------- animated sky (sky-anim.js) ---------- */

/* body becomes a stacking context, so the z-index:-1 canvas paints above
   body's own gradient but below all content (without this it is hidden:
   <html> has its own background, so body's gradient is painted as a block
   on top of negative z-index layers). */
body { isolation: isolate; }

.sky-anim {
  position: fixed;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.8s ease-in-out;
}

/* Fades in when a scene starts; the script adds/removes .on. */
.sky-anim.on { opacity: 1; }

.motion-toggle { display: flex; align-items: center; gap: 8px; margin-top: 16px; font-weight: 600; }
.motion-toggle input { width: 18px; height: 18px; accent-color: var(--button-bg); }
.motion-toggle + .setting-hint { margin-top: 4px; }

@media (prefers-reduced-motion: reduce) {
  .sky-anim { display: none; }
}

/* ================= warnings ================= */
/* ---------- official warnings ---------- */

/* Opaque banners (--banner: white on light skies, deep navy on dark ones) so
   the relayed text never sits on glass; the level shows as a 6 px stripe and
   a badge that names it, so colour is never the only cue. */
.warnings { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; scroll-margin-top: 76px; }

/* A yellow warning for the place, named at the top of the main card's summary
   while its card sits below the hourly strip; a tap goes there. */
.warn-pointer button { color: inherit; font-weight: 600; text-align: start; text-underline-offset: 3px; }
.warnings h2 { margin-bottom: 0; }

.warn {
  --warn: var(--track);
  border-inline-start: 6px solid var(--warn);
  border-radius: 14px;
  background: var(--banner);
  color: var(--text);
}
.warn-yellow { --warn: #f7d51d; }
.warn-orange { --warn: #f7862a; }
.warn-red { --warn: #d92b3a; }

.warn summary,
.warn-head {
  display: grid;
  justify-items: start;
  gap: 3px;
  padding: 10px 14px 4px;
}
.warn summary {
  position: relative;
  padding-inline-end: 40px;
  border-radius: 14px;
  list-style: none;
  cursor: pointer;
}
.warn summary::-webkit-details-marker { display: none; }
/* Chevron: points down when closed, up when open. */
.warn summary::after {
  content: '';
  position: absolute;
  top: 16px;
  inset-inline-end: 16px;
  width: 8px;
  height: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  opacity: 0.7;
  transform: rotate(45deg);
  transition: transform 0.2s;
}
.warn details[open] > summary::after { transform: translateY(4px) rotate(-135deg); }

/* Dark ink on yellow/orange, white on red: all ≥ 4.8:1. */
.warn-level {
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--warn);
  color: #1a1300;
  font-size: 12px;
  font-weight: 700;
}
.warn-red .warn-level { color: #ffffff; }
.warn-info .warn-level { color: var(--text); }

/* Full width so dir="auto" aligns English NWS text left even in the Hebrew UI. */
.warn-title,
.warn-region { justify-self: stretch; }
.warn-title { font-size: 15px; font-weight: 600; }
.warn-region,
.warn-time { font-size: 13px; color: var(--text-dim); }

.warn-text {
  padding: 4px 14px 6px;
  font-size: 14px;
  line-height: 1.5;
  white-space: pre-line; /* NWS paragraphs */
  overflow-wrap: anywhere;
}
.warn-source {
  padding: 2px 14px 10px;
  font-size: 12px;
  color: var(--text-dim);
}
.warn-note { font-size: 12px; color: var(--text-dim); }

/* The check of official warnings failed (warnings.js warningsCheckHtml). */
.warn-check {
  display: flex;
  gap: 8px;
  padding: 8px 12px;
  border-radius: 12px;
  border-inline-start: 5px solid #ffb020;
  background: var(--tile);
  font-size: 14px;
}
.warn-check a { color: inherit; font-weight: 600; white-space: nowrap; }

/* "Translate with Google Translate" under a description in another language:
   one small link, like the source line, with room for a finger on a phone. */
.warn-translate { padding: 0 14px 6px; font-size: 13px; }
.warn-translate a { display: inline-block; padding: 4px 0; color: var(--text-dim); }

/* Settings: "Delete my data". */
.data-delete,
.data-actions .text-btn { border-color: transparent; background: var(--hover); }
.data-confirm { font-weight: 600; }
.data-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.pill-btn.data-yes { background: #b3261e; color: #ffffff; }

@media (prefers-reduced-motion: reduce) {
  .warn summary::after { transition: none; }
}

/* ================= sea ================= */
/* ---------- sea & beaches ---------- */

.sea-hint {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
  padding: 8px 12px;
  border-radius: 12px;
  border-inline-start: 5px solid;
  background: var(--tile);
  font-size: 14px;
  font-weight: 600;
}

/* Low waves are a fact, not a go-ahead: a neutral sea blue, not green. */
.sea-hint.low { border-color: #3d8fd6; }
.sea-hint.rough { border-color: #d92f4f; }

/* Two periods side by side even on phones; a lone one takes the full width. */
.sea-periods {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(135px, 100%), 1fr));
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.sea-period {
  display: grid;
  align-content: start;
  gap: 4px;
  padding: 10px 12px;
  border-radius: 14px;
  background: var(--tile);
}

.sea-when {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 0 8px;
}

.sea-when small, .sea-waves small { font-size: 12px; color: var(--text-dim); }
.sea-waves { display: grid; margin-top: 2px; }
.sea-waves b { font-size: 20px; }
.sea-state { font-size: 14px; font-weight: 600; }
/* Label | value rows, aligned across rows. */
.sea-facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2px 6px;
  margin: 2px 0 0;
  font-size: 13px;
}

.sea-facts div { display: contents; }
.sea-facts dt { color: var(--text-dim); white-space: nowrap; }
.sea-facts dd { margin: 0; }
.sea-speed { white-space: nowrap; }
.sea-safety { display: flex; gap: 6px; margin-top: 12px; font-size: 13px; }
.sea-source { margin-top: 6px; font-size: 12px; color: var(--text-dim); }
.sea-source a { font-weight: 600; }

/* The Israel Meteorological Service's required disclaimer, beside its warnings,
   its sea forecast and its credit: small, but in full-contrast ink rather than
   the dim one, so it stays conspicuous. */
.ims-note { font-size: 12px; line-height: 1.45; color: var(--text); }
.sea-card .ims-note { margin-top: 4px; }
.credits .ims-note { color: var(--text); }

/* Extra official warnings fold away under "N more"; those for other parts of
   Israel under one line that opens in place. Each is a row a finger can hit. */
.warn-more { display: grid; gap: 10px; }
.warn-more > summary {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 8px 40px 8px 14px;
  border-radius: 14px;
  background: var(--tile);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.35;
  list-style: none;
  cursor: pointer;
}
:root[dir='rtl'] .warn-more > summary { padding: 8px 14px 8px 40px; }
.warn-more > summary::-webkit-details-marker { display: none; }
.warn-more > summary::after {
  content: '';
  position: absolute;
  top: 50%;
  inset-inline-end: 16px;
  width: 8px;
  height: 8px;
  margin-top: -6px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  opacity: 0.7;
  transform: rotate(45deg);
  transition: transform 0.2s;
}
.warn-more[open] > summary::after { transform: translateY(4px) rotate(-135deg); }
.warn-dots { display: inline-flex; flex: none; gap: 3px; }
.warn-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--warn, var(--track)); box-shadow: 0 0 0 1px var(--bar-outline); }

@media (prefers-reduced-motion: reduce) {
  .warn-more > summary::after, .d-chev { transition: none; }
}

/* ---------- units & language ---------- */

/* Language: the section's title and the picker on one row. */
.lang-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 4px; }
.sheet .lang-row h3 { margin: 0; }

.unit-grid { display: grid; gap: 10px; }
/* A long choice ("inches of mercury (inHg)") moves under its label on a narrow phone. */
.unit-grid label { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 12px; }
.unit-grid select { max-width: 100%; margin-inline-start: auto; }

.unit-grid select,
.lang-select {
  min-height: 36px;
  padding: 4px 10px;
  border: 1px solid var(--card-border);
  border-radius: 999px;
  background: var(--chip);
  color: var(--text);
  font: inherit;
  font-size: 14px;
}

.lang-select option, .unit-grid option { background: var(--menu); color: var(--text); }

/* ================= map ================= */
/* ---------- clouds & rain map (js/map.js) ---------- */

/* Cloud colour on the map; keep in sync with CLOUD_TINT in map.js. */
.map-card { --map-cloud: rgb(84, 100, 122); }
:root[data-mode='dark'] .map-card { --map-cloud: #ffffff; }

/* Card header: title plus the layer toggle, like the meteogram's. */
.map-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
  margin-bottom: 12px;
}

.card .map-head h2 { margin: 0; }

.map-toggle {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  background: var(--track);
}

.map-toggle button {
  min-height: 30px;
  padding: 4px 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font-size: 13px;
  white-space: nowrap;
}

@media (hover: hover) {
  .map-toggle button:hover { background: var(--hover); }
}

.map-toggle button[aria-pressed='true'] {
  background: var(--chip-active);
  box-shadow: 0 0 0 1px var(--chip-active-border), var(--card-shadow);
  font-weight: 600;
}

/* The map box; MapLibre fills .map-canvas. */
.map-view {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  max-height: 380px;
  overflow: hidden;
  border: 1px solid var(--divider);
  border-radius: 14px;
  background: var(--tile);
  isolation: isolate;
}

/* Beats .maplibregl-map { position: relative }, which loads later. */
.map-view > .map-canvas { position: absolute; inset: 0; }

/* Loading / error text, centred over the map on a solid pill. */
.map-msg {
  position: absolute;
  inset-inline: 16px;
  top: 50%;
  z-index: 3;
  width: fit-content;
  max-width: calc(100% - 32px);
  margin-inline: auto;
  padding: 6px 14px;
  transform: translateY(-50%);
  border-radius: 999px;
  background: var(--menu);
  color: var(--text);
  font-size: 14px;
  text-align: center;
  pointer-events: none;
}

.map-note { margin-top: 8px; font-size: 13px; color: var(--text-dim); }

.map-key {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 6px;
  margin-top: 4px;
  font-size: 12px;
  color: var(--text-dim);
}

.map-swatch {
  display: inline-block;
  width: 14px;
  height: 10px;
  border: 1px solid var(--bar-outline);
  border-radius: 3px;
}

.map-swatch-cloud { background: var(--map-cloud); }
.map-swatch-storm { background: linear-gradient(to right, #66ff00, #ffcc00, #ff0000, #bf40a5); }
.map-swatch-snow { background: linear-gradient(to right, #b1faee, #4b6ac7, #7010e1); }
/* Light → heavy runs from the inline start. */
.map-swatch-rain { width: 48px; background: linear-gradient(to right, #00764e, #45c000, #e6ec00, #ff7a1a, #ff0101, #9c0000); }
:root[dir='rtl'] .map-swatch-rain { background: linear-gradient(to left, #00764e, #45c000, #e6ec00, #ff7a1a, #ff0101, #9c0000); }

/* MapLibre controls in the app's colours. */
.map-card .maplibregl-ctrl-group { background: var(--menu); box-shadow: 0 0 0 1px var(--divider); }
.map-card .maplibregl-ctrl-group button + button { border-top-color: var(--divider); }
/* The credits are English, so left-to-right even on a right-to-left page (this
   also keeps MapLibre's "i" button on the side its padding expects). */
.map-card .maplibregl-ctrl.maplibregl-ctrl-attrib {
  direction: ltr;
  background-color: color-mix(in srgb, var(--menu) 90%, transparent);
  color: var(--text);
  font-size: 10px;
}
.map-card .maplibregl-ctrl-attrib a { color: inherit; }
:root[data-mode='dark'] .map-card .maplibregl-ctrl-icon,
:root[data-mode='dark'] .map-card .maplibregl-ctrl-attrib-button { filter: invert(1); }
.map-card .maplibregl-cooperative-gesture-screen { font-size: 15px; }
.map-card .maplibregl-canvas:focus-visible { outline: 2px solid var(--text); outline-offset: -2px; }

/* map.js adds /js/vendor/maplibre/maplibre-gl.css itself when the card first loads; nothing to add to index.html. */

/* ================= trips ================= */
/* ---------- "My trips" (trips-ui.js) ---------- */

/* "Plan a trip here" on the current card, beside share and favourite. */
.trip-btn {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-block: -2px;
  border: 0;
  border-radius: 50%;
  background: transparent;
}
.trip-btn svg { width: 22px; height: 22px; }

/* Trips under way or coming up, before the favourites (which keep their size). */
.chips { align-items: center; }
.chip.trip-chip { min-height: 44px; font-weight: 600; }

/* The one reminder above the forecast: its text, "View" and a small ×. */
.trip-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  padding-block: 4px;
}
.trip-banner p { flex: 1 1 12rem; min-width: 0; padding-block: 6px; overflow-wrap: anywhere; }
.trip-banner-actions { display: flex; align-items: center; gap: 2px; margin-inline-start: auto; }
.trip-banner .text-btn { min-height: 44px; }
.trip-banner.warn-orange, .trip-banner.warn-red { border-inline-start-color: var(--warn); }

/* A small × a finger can still hit (the reminder, an own packing item). */
.icon-btn.small.trip-close,
.trips-sheet .sheet-head .icon-btn.small { width: 44px; height: 44px; }
.icon-btn.small.trip-close { border-color: transparent; background: transparent; }

/* The dialog: one column that never grows sideways (long names, 200% text). */
.trips-sheet { width: min(600px, calc(100vw - 32px)); }
#trips-title { min-width: 0; overflow-wrap: anywhere; }
#trips-body,
.trip-view,
.trip-list-view,
.trip-form,
.trip-sec { display: grid; grid-template-columns: minmax(0, 1fr); }
.trip-view, .trip-list-view, .trip-form { gap: 14px; }
.trip-sec { gap: 8px; padding-top: 14px; border-top: 1px solid var(--divider); }
.trip-compare-controls, .trip-compare-cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
.trip-compare-controls select { width: 100%; min-width: 0; min-height: 44px; color: var(--text); background: var(--chip); }
.trip-activity-controls { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
.trip-activity-controls select { width: 100%; min-width: 0; min-height: 44px; color: var(--text); background: var(--chip); }
.trip-activity-results { min-width: 0; overflow-wrap: anywhere; }
.trip-activity .act-windows { margin-block: 4px; }
.trip-activity .act-rules { margin-block: 8px; }
.trip-compare-card { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; padding: 12px; border: 1px solid var(--divider); border-radius: 14px; overflow-wrap: anywhere; }
.trip-compare-card h4, .trip-compare-card h5 { margin: 0; font-size: 16px; }
.trip-compare-card .warnings { margin: 0; padding: 8px; }
.trip-compare-values { display: grid; gap: 8px; margin: 0; }
.trip-compare-values > div { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; }
.trip-compare-values dt { color: var(--text-dim); font-size: 13px; }
.trip-compare-values dd { min-width: 0; margin: 0; font-weight: 600; }
.trip-compare-values small { display: block; font-size: 12px; font-weight: 400; color: var(--text-dim); }
@media (min-width: 560px) { .trip-compare-controls { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 560px) { .trip-activity-controls { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.trips-sheet p { margin: 0; }
.trips-sheet h3 { margin: 0; }
.trip-sub { font-size: 13px; font-weight: 600; color: var(--text-dim); }
.trip-note, .trip-stamp, .trip-status, .trip-fold { font-size: 13px; color: var(--text-dim); }
.trip-fold { color: var(--text); }
.trips-sheet .link-btn { display: inline-block; margin-block: -12px; padding: 12px 4px; }
.trip-buttons { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.trip-buttons .pill-btn, .trip-buttons .text-btn, .trip-add { min-height: 44px; }
.trip-add { justify-self: start; }
.pill-btn:disabled { opacity: 0.45; cursor: default; }

/* The list: each trip a row that opens it. */
.trip-list { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.trip-row {
  display: grid;
  gap: 2px;
  width: 100%;
  min-height: 44px;
  padding: 10px 14px;
  border: 1px solid var(--divider);
  border-radius: 14px;
  background: var(--hover);
  color: inherit;
  font: inherit;
  text-align: start;
  overflow-wrap: anywhere;
}
.trip-row-name b { font-size: 16px; }
.trip-row-name small, .trip-row-dates { font-size: 13px; color: var(--text-dim); }
.trip-row-status { font-size: 14px; font-weight: 600; color: var(--accent-ink); }
.trip-row-status.is-over { font-weight: 400; color: var(--text-dim); }

/* The form. */
.trip-field { display: grid; gap: 6px; min-width: 0; }
.trip-label { font-size: 14px; font-weight: 600; }
.trip-dates { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(10rem, 100%), 1fr)); gap: 12px; }
.trip-input {
  width: 100%;
  min-width: 0;
  min-height: 44px;
  padding: 6px 12px;
  border: 1px solid var(--bar-outline);
  border-radius: 12px;
  background: var(--menu);
  color: var(--text);
  font: inherit;
  font-size: 16px; /* no zoom on focus */
}
.trip-search { display: grid; gap: 6px; min-width: 0; }
.results.trip-results { position: static; max-height: none; box-shadow: none; border: 1px solid var(--divider); }
.trip-dest { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; }
.chip.trip-dest-chip { font-size: 15px; font-weight: 600; white-space: normal; overflow-wrap: anywhere; background: var(--hover); }
.trip-dest-chip small { font-weight: 400; color: var(--text-dim); }
.trip-confirm { font-weight: 600; }
.trip-error { font-weight: 600; color: var(--danger); }

/* A trip: the countdown, then the sections. */
.trip-count-big { font-size: 22px; font-weight: 700; line-height: 1.3; }
.trip-count-sub { font-size: 14px; color: var(--text-dim); }
.trips-sheet .warnings { padding: 0; border: 0; background: none; box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none; }
.trips-sheet .warnings h3 { font-size: 15px; color: var(--text); }
.trip-nowarn { padding: 8px 12px; border-radius: 12px; border-inline-start: 5px solid var(--track); background: var(--hover); font-size: 14px; }
.trip-nowarn a { display: inline-block; margin-block: -12px; padding-block: 12px; font-weight: 600; }

/* The days: the main screen's daily rows, without the button. */
@media (hover: hover) {
  .trip-day .d-row:hover { background: none; }
}
.trip-day .d-precip { display: grid; justify-items: start; gap: 2px; }
.uv-pill.trip-uv { padding: 0 6px; font-size: 11px; line-height: 1.5; white-space: nowrap; }

/* Home and destination. */
.trip-home-line { font-weight: 600; }
.trip-chips { justify-content: flex-start; }
.trip-chips .chip { min-height: 44px; white-space: normal; }
.trip-sun { display: grid; gap: 6px; padding: 10px 12px; border-radius: 14px; background: var(--hover); }
/* Sunrise, day length and sunset three across, as on the sun card, in the
   narrower dialog; one under the other once they don't fit (large text),
   never two and then one alone: each takes the whole row below 15rem. */
.trip-sun .sun-times { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 0; }
.trip-sun .sun-times > div { flex: 1 1 calc((15rem - 100%) * 999); min-width: 0; }
.trip-sun .sun-polar { text-align: start; }
.trip-compare { display: grid; gap: 6px; }
.trip-pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(8rem, 100%), 1fr)); gap: 8px; margin: 0; }
.trip-pair div { padding: 8px 12px; border-radius: 14px; background: var(--hover); }
.trip-pair dt { font-size: 13px; color: var(--text-dim); overflow-wrap: anywhere; }
.trip-pair dd { margin: 0; font-size: 17px; font-weight: 600; }

/* What to pack: a checkbox row per item, the reason under it. */
.trip-checks { display: grid; margin: 0; padding: 0; list-style: none; }
.trip-checks li { display: flex; align-items: center; gap: 4px; }
.trip-checks li + li { border-top: 1px solid var(--divider); }
.trip-check { display: flex; flex: 1; align-items: center; gap: 12px; min-width: 0; min-height: 44px; padding: 6px 0; cursor: pointer; }
.trip-check input { flex: none; width: 22px; height: 22px; margin: 0; accent-color: var(--button-bg); }
.trip-check > span { display: grid; min-width: 0; overflow-wrap: anywhere; }
.trip-check small { font-size: 13px; color: var(--text-dim); }
.trip-check input:checked + span { opacity: 0.7; }
/* The field and "Add" share a row; on a narrow screen (large text) "Add" goes under it. */
.trip-own-add { display: flex; flex-wrap: wrap; gap: 8px; }
.trip-own-add .trip-input { flex: 1 1 8rem; width: auto; }
.trip-own-add .text-btn { flex: none; min-height: 44px; }

/* ================= best time for ================= */
/* ---------- "Best time for…" (activities-ui.js) ---------- */

/* The card: its title and "Choose activities"; the button wraps under the
   title on a narrow screen or at large text. */
.act-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 12px;
  margin-bottom: 6px;
}
.card .act-head h2 { margin: 0; }
.act-choose { min-height: 44px; }
.act-empty { font-size: 14px; }

/* One row per activity, a button that opens its details under it (like a day). */
.act-list { margin: 0; padding: 0; list-style: none; }
.act + .act { border-top: 1px solid var(--divider); }
.act-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 44px;
  padding: 8px 0;
  border: 0;
  border-radius: 10px;
  background: none;
  color: inherit;
  font: inherit;
  text-align: start;
}
@media (hover: hover) {
  .act-row:hover { background: var(--hover); }
}
.act-emoji { flex: none; width: 1.6em; font-size: 20px; line-height: 1; text-align: center; }
.act-text { display: grid; flex: 1; min-width: 0; overflow-wrap: anywhere; }
.act-name { font-weight: 600; }
.act-when { font-size: 14px; }
.act.is-none .act-when { color: var(--text-dim); }
.act.open .d-chev { transform: translateY(2px) rotate(-135deg); }

/* The opened row: the good times on a tile, then the conditions. */
.act-more { display: grid; gap: 6px; padding-block: 0 12px; }
.act-windows { display: grid; gap: 4px; margin: 0; padding: 8px 12px; list-style: none; border-radius: 14px; background: var(--tile); font-size: 14px; }
.act-windows .is-best { font-weight: 600; }
.act-hours { font-size: 12px; font-weight: 400; color: var(--text-dim); white-space: nowrap; }
.act-best {
  display: inline-block;
  padding: 0 8px;
  border-radius: 999px;
  background: var(--chip-active);
  box-shadow: 0 0 0 1px var(--bar-outline);
  font-size: 12px;
  font-weight: 600;
}
.act-rules { font-size: 13px; color: var(--text-dim); }
.act-basis { margin-block: 2px 8px; font-size: 13px; color: var(--text-dim); }
.act-context { margin: 0; padding-block: 0 8px; font-size: 13px; font-weight: 400; overflow-wrap: anywhere; }
.act-context.has-warning { border-inline-start: 3px solid var(--text); padding-inline-start: 10px; }
.act-warning-inline { display: inline-block; border-inline-start: 3px solid var(--warn); padding-inline-start: 8px; }
.act-warning-link { min-height: 44px; text-align: start; white-space: normal; font-weight: 600; }
.banner time { white-space: normal; }

/* The dialog: one column that never grows sideways (long names, 200% text). */
.act-sheet .sheet-head .icon-btn.small { width: 44px; height: 44px; }
#activities-title { min-width: 0; overflow-wrap: anywhere; }
#activities-body,
.act-editor,
.act-form,
.act-sec { display: grid; grid-template-columns: minmax(0, 1fr); }
.act-editor, .act-form { gap: 14px; }
.act-sec { gap: 6px; padding-top: 14px; border-top: 1px solid var(--divider); }
.act-sheet p, .act-sheet h3 { margin: 0; }
.act-note { font-size: 13px; color: var(--text-dim); }
.act-note.act-full { font-weight: 600; color: var(--text); }

/* Each activity a checkbox, its conditions under its name; the user's own
   with Edit and Delete, which go under it when the row is too narrow. */
.act-picks { display: grid; margin: 0; padding: 0; list-style: none; }
.act-picks li { display: flex; flex-wrap: wrap; align-items: center; gap: 0 8px; }
.act-picks li + li { border-top: 1px solid var(--divider); }
.act-check { display: flex; flex: 1 1 12rem; align-items: center; gap: 12px; min-width: 0; min-height: 44px; padding: 6px 0; cursor: pointer; }
.act-check input { flex: none; width: 22px; height: 22px; margin: 0; accent-color: var(--button-bg); }
.act-check > span { display: grid; min-width: 0; overflow-wrap: anywhere; }
.act-check-name { font-weight: 600; }
.act-check small { font-size: 13px; color: var(--text-dim); }
.act-check input:disabled { cursor: default; }
.act-check input:disabled + span { opacity: 0.6; }
.act-own-btns { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; margin-inline-start: auto; padding-block: 4px; }
.act-own-btns .text-btn, .act-new { min-height: 44px; }
.act-new { justify-self: start; margin-top: 4px; }

/* The form: native fields, each with its label in view. */
.act-field { display: grid; gap: 6px; min-width: 0; }
.act-label { font-size: 14px; font-weight: 600; }
.act-sub { font-size: 14px; }
.act-feels { display: grid; gap: 6px; min-width: 0; margin: 0; padding: 0; border: 0; }
.act-feels legend { margin-bottom: 6px; padding: 0; }
.act-pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(8rem, 100%), 1fr)); gap: 12px; }

/* ================= my places ================= */
/* ---------- the main card, the chips and Settings (settings-ui.js) ---------- */

/* The user's own name for the place ("Home"), above the city's name. */
.place-label { font-size: 14px; font-weight: 600; color: var(--text-dim); overflow-wrap: anywhere; }

/* Settings: each favourite with Rename, up, down and Remove, 44 px each. */
.fav-list { margin: 0; padding: 0; list-style: none; }
.fav-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 8px;
  padding: 6px 0;
  border-top: 1px solid var(--divider);
}
.fav-name { display: grid; min-width: 0; overflow-wrap: anywhere; font-weight: 600; }
.fav-name small { font-size: 13px; font-weight: 400; color: var(--text-dim); }
/* At 200% text the buttons wrap under the name, never off the side. */
.fav-btns { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 6px; margin-inline-start: auto; }
.fav-btns .text-btn { min-height: 44px; }
.fav-btns .icon-btn.small { width: 44px; height: 44px; }
.icon-btn.small.fav-remove { border-color: transparent; background: transparent; }
.fav-edit { display: grid; flex: 1 1 100%; gap: 6px; min-width: 0; padding-block: 4px; }
.sheet .fav-edit p { margin: 0; }
.fav-edit .trip-buttons .pill-btn, .fav-edit .trip-buttons .text-btn { min-height: 44px; }

/* "When the app opens": the label and the choice on one row, or two. */
.start-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 12px; margin-top: 12px; }
.start-row select {
  max-width: 100%;
  min-height: 44px;
  margin-inline-start: auto;
  padding: 4px 10px;
  border: 1px solid var(--card-border);
  border-radius: 999px;
  background: var(--chip);
  color: var(--text);
  font: inherit;
  font-size: 14px;
}
.start-row option { background: var(--menu); color: var(--text); }

/* "How do you feel the weather?": three choices, a finger's height each. */
.feel-options { display: grid; }
.feel-option { display: flex; align-items: center; gap: 10px; min-height: 44px; cursor: pointer; }
.feel-option input { flex: none; width: 20px; height: 20px; margin: 0; accent-color: var(--button-bg); }

/* ================= large text ================= */
/* Android's font size setting zooms the page in Chrome and in the installed
   app: at 150% a 360 px phone is 240 CSS px wide, at 200% only 180. Nothing
   may run off the side: rows wrap, and the biggest things get smaller. */
.place-row > div:first-child { min-width: 0; }
.place-name > bdi { min-width: 0; overflow-wrap: break-word; }
.mg-toggle { max-width: 100%; flex-wrap: wrap; }

@media (max-width: 300px) {
  .wrap { padding-inline: 10px; }
  .topbar { margin-inline: -10px; padding-inline: 10px; }
  .card, .sheet { padding: 14px 12px; }
  .place-row { flex-wrap: wrap; gap: 0 8px; }
  .place-actions { margin-inline-start: auto; }
  .now { flex-wrap: wrap; }
  .now-icon { width: 52px; height: 52px; }
  .now-temp { font-size: 52px; }
  .warn-check a { white-space: normal; }
  .mg-toggle { border-radius: 16px; }
  .mg-toggle button { padding-inline: 8px; }
  .credit span { display: inline; }
  .jw-holidays li { flex-wrap: wrap; }
}

/* ================= wide screens ================= */
/* ---------- tablets and desktops (720 px and wider) ---------- */

/* From 720 px (tablets in either orientation, desktops, phones on their side)
   the page is not one phone-width column: the current conditions, the
   official warnings and (when it is the first card) the hourly strip run the
   full width, and the other cards flow down two balanced columns. The flow is
   column by column in the saved card order, so moving or hiding a card needs
   nothing here, and a card is never split between columns. Each column is at
   least as wide as a phone screen (328 px at 720). */
@media (min-width: 720px) {
  .wrap {
    max-width: 1360px;
    padding-left: max(24px, env(safe-area-inset-left));
    padding-right: max(24px, env(safe-area-inset-right));
  }
  .topbar { margin-inline: -24px; padding-inline: 24px; }
  /* Place names are short: the list keeps to the search box's inline start. */
  .results { max-width: 640px; }

  main { display: block; columns: 2; column-gap: 16px; }
  main > * { break-inside: avoid; margin: 0 0 16px; }
  main > :is(.banner, .current, .warnings, .welcome, .message) { column-span: all; }
  main > :is(.welcome, .message) { max-width: 680px; margin-inline: auto; }
  /* A lone card after the full-width ones takes the whole row too. */
  main > :is(.current, .warnings) + .card:last-child { column-span: all; }

  /* Current conditions: the headline (icon, temperature, feels like) at the
     inline start and the day's summary and hints beside it. */
  .current {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: start;
    column-gap: 28px;
  }
  .current > .place-row, .current > .stamp { grid-column: 1 / -1; }
  .current > .now-more { margin-top: 8px; }
  .current > .now-more > .summary:first-child { margin-top: 0; }

  /* The two open warnings side by side when they fit (one alone takes the
     whole row); the title, the notes and the "N more" fold stay full width. */
  .warnings { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 10px 12px; }
  .warnings > * { flex: 1 1 100%; }
  .warnings > .warn { flex: 1 1 360px; }
}

/* Columns narrower than about 420 px: the phone's tighter day rows. */
@media (min-width: 720px) and (max-width: 959.98px) {
  .day { --dn: 3.3rem; --dp: 2.8rem; --dt: 2.1rem; --dg: 5px; font-size: 14px; }
  .d-icon { width: 32px; height: 32px; }
  .d-precip { font-size: 11px; }
}

/* Rules that need :has(), kept apart so a browser without it skips only
   these: the hourly strip runs the full width when it is the first card, and
   the welcome screen's search bar matches its card. */
@media (min-width: 720px) {
  main > .current + .card:has(> .hourly),
  main > .current + .warnings + .card:has(> .hourly),
  main > .current + .card:has(> .hourly) + .card:last-child,
  main > .current + .warnings + .card:has(> .hourly) + .card:last-child { column-span: all; }
  .wrap:has(> main > .welcome) > .topbar { max-width: 728px; margin-inline: auto; }
}
/* ================= end of wide screens ================= */
