/* Overlay widths: one width for every single-column window, and a wider one only where two columns sit side by side. */
:root {
  --panel-md: 640px;
  --panel-lg: 820px;
}

@font-face {
  font-family: "Open Sans";
  src: url("./assets/OpenSans-Regular.ttf") format("truetype");
}

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  overflow: hidden;
  background: var(--color-page, var(--color-bg));
  color: var(--color-fg-1);
  font-family: "Open Sans", system-ui, sans-serif;
  transition: background-color .3s ease-out;
}

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

button {
  -webkit-appearance: none;
  appearance: none;
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}

:focus-visible {
  outline: 2px solid var(--color-border-hover);
  outline-offset: 4px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}

#container {
  position: relative;
  height: 100vh;
  height: 100svh;
  min-height: 100vh;
  min-height: 100svh;
  overflow: hidden;
}

.blob {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
}

.blob-a {
  width: 900px;
  height: 900px;
  left: -320px;
  top: -360px;
  background: radial-gradient(circle, var(--color-blob-a) 0%, transparent 65%);
}

.blob-b {
  width: 820px;
  height: 820px;
  right: -300px;
  bottom: -340px;
  background: radial-gradient(circle, var(--color-blob-b) 0%, transparent 65%);
}

/* Top bar: shortcut left, date and time centred, theme switch right. */
.topbar {
  position: absolute;
  top: 20px;
  left: 24px;
  right: 24px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  z-index: 1;
}

.topbar .icon-link,
.modes button {
  display: flex;
  align-items: center;
  padding: 6px;
  border-radius: 6px;
  color: var(--color-fg-2);
  transition: color .2s ease-in-out;
}

.topbar .icon-link:hover,
.topbar .icon-link:focus-visible,
.modes button:hover,
.modes button:focus-visible {
  color: var(--color-fg-1);
}

.modes {
  display: flex;
  align-items: center;
}

.modes button[aria-pressed="true"] {
  color: var(--color-fg-1);
}

#clock {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin-bottom: 36px;
  color: var(--color-fg-1);
  text-align: center;
  font-variant-numeric: tabular-nums;
}

#time {
  font-size: 24px;
  font-weight: 400;
  letter-spacing: .02em;
  opacity: .8;
  cursor: pointer;
}

#date {
  font-size: 12px;
  letter-spacing: .06em;
  color: var(--color-fg-2);
  cursor: pointer;
}

/* Centred column: search field and shortcut row. */
#main {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 16px;
}

#main > * {
  width: 100%;
  max-width: 360px;
}

/* The search sits in the middle; the clock is placed above it and the AI row below, so neither moves it. */
.centre {
  position: relative;
}

.centre > #clock {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
}

/* On a computer the quote stays near the bottom of the page, as before. */
.centre > .quote {
  position: fixed;
}

.centre > .links {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  margin-top: 24px;
}

#main {
  transform: translateY(-56px);
}

.searchbar {
  position: relative;
  display: block;
}

#search {
  width: 100%;
  height: 48px;
  padding: 0 84px;
  background: var(--color-field);
  color: var(--color-fg-1);
  border: 1px solid var(--color-border);
  border-radius: 12px;
  font: 400 15px "Open Sans", system-ui, sans-serif;
  text-align: center;
  transition: border-color .2s ease-in-out;
}

#search::placeholder {
  color: var(--color-fg-2);
}

#search:focus {
  outline: none;
  border-color: var(--color-border-hover);
}

#engine {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 28px;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  color: var(--color-fg-2);
  transition: color .2s ease-in-out, border-color .2s ease-in-out;
}

#engine:hover,
#engine:focus-visible {
  color: var(--color-fg-1);
  border-color: var(--color-border-hover);
}

#engine svg {
  display: block;
}

/* Submit button on the right: clearly clickable, with a hover state. */
#go {
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  width: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-fg-2);
  border-radius: 0 12px 12px 0;
  transition: color .2s ease-in-out;
}

/* Hover changes colour only, so the field's bottom border stays unbroken. */
#go:hover,
#go:focus-visible {
  color: var(--color-fg-1);
}

.links {
  margin-top: 40px;
}

.caption {
  margin-bottom: 12px;
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  text-align: center;
  color: var(--color-fg-2);
  opacity: .6;
}

/* The padding makes the whole link easy to hit; the negative margin keeps the footer where it was. */
footer a {
  display: inline-block;
  padding: 12px 8px;
  margin: -12px -8px;
  color: inherit;
  text-decoration: none;
}

footer a:hover svg,
footer a:focus-visible svg {
  color: #d64545;
}

/* Weather, centred in the top bar. The details show on hover, focus or a click. */
/* Centred on the page itself, not between the two icons, which differ in width. */
.weather {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1;
  font-size: 12px;
  color: var(--color-fg-2);
}

.weather-icon {
  display: inline-block;
  vertical-align: -2px;
  margin-right: 6px;
}

.weather button {
  padding: 6px 8px;
  border-radius: 6px;
  color: inherit;
  font-variant-numeric: tabular-nums;
  transition: color .2s ease-in-out;
}

.weather button:hover,
.weather button:focus-visible {
  color: var(--color-fg-1);
}

.weather-detail {
  display: none;
  position: absolute;
  top: 100%;
  margin-top: 8px;
  left: 50%;
  transform: translateX(-50%);
  min-width: 280px;
  padding: 16px 18px;
  background: var(--color-field);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  color: var(--color-fg-1);
  line-height: 1.7;
  z-index: 2;
}

.weather-detail:empty {
  display: none !important;
}

/* Invisible bridge over the gap, so the preview stays open while the pointer moves down into it. */
.weather-detail::before {
  content: "";
  position: absolute;
  top: -8px;
  left: 0;
  right: 0;
  height: 8px;
}

.weather-detail {
  cursor: pointer;
}

.weather:hover .weather-detail,
.weather:focus-within .weather-detail,
.weather-detail.open {
  display: block;
}

.weather-row {
  display: grid;
  grid-template-columns: 1fr 4ch 5ch;
  gap: 16px;
  padding: 3px 0;
  font-variant-numeric: tabular-nums;
}

.weather-row > span + span {
  text-align: right;
}

/* Time zone lines have a name and a time, and a day word that may be longer. */
.weather-row.zone-line {
  grid-template-columns: minmax(0, 1fr) 7ch 6ch 1fr;
  gap: 12px;
}

.weather-row + .weather-row {
  color: var(--color-fg-2);
}

.preview-title {
  margin-bottom: 8px;
  font-weight: 600;
  color: var(--color-fg-1);
}

.preview-hint {
  margin-top: 10px;
  font-size: 11px;
  color: var(--color-fg-2);
}


footer svg {
  display: inline-block;
  vertical-align: -1px;
  margin: 0 3px;
}

footer a:focus-visible {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Icons sit in a tight, centred group so the row reads as one unit. */
.links ul {
  display: flex;
  justify-content: center;
  gap: 8px;
  list-style: none;
}

.links a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  color: var(--color-fg-2);
  opacity: .7;
  transition: color .2s ease-in-out, opacity .2s ease-in-out;
}

.links a:hover,
.links a:focus-visible {
  color: var(--color-fg-1);
  opacity: 1;
}

/* Quote of the day sits between the AI row and the footer, out of the column's flow. */
.quote {
  position: absolute;
  left: 24px;
  right: 24px;
  bottom: 164px;
  max-width: 360px;
  margin: 0 auto;
  padding: 4px 8px;
  font-size: 14px;
  line-height: 1.6;
  text-align: center;
  color: var(--color-fg-2);
  opacity: .7;
  cursor: pointer;
  transition: opacity .3s ease-in-out, color .3s ease-in-out;
}

.quote:hover,
.quote:focus-visible {
  color: var(--color-fg-1);
  opacity: 1;
}

#quote-by {
  display: block;
  margin-top: 6px;
  font-size: 11px;
  letter-spacing: .04em;
  opacity: .8;
}

footer {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 28px;
  text-align: center;
  font-size: 10px;
  letter-spacing: .06em;
  color: var(--color-fg-2);
  opacity: .6;
}

/* Wallpaper mode: one photo behind the page, with a stronger veil so the text stays readable. */
.wallpaper {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 0;
  transition: opacity .6s ease-out;
  pointer-events: none;
}

.wallpaper::after {
  content: "";
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--color-bg) 78%, transparent);
}

html[data-wallpaper-on] .wallpaper {
  opacity: 1;
}

html[data-wallpaper-on] .blob {
  display: none;
}

html[data-wallpaper-on] .quote {
  color: var(--color-fg-1);
  opacity: .9;
}

html[data-wallpaper-on] footer {
  color: var(--color-fg-1);
  opacity: .85;
}

html[data-wallpaper-on] .topbar .icon-link,
html[data-wallpaper-on] .modes button {
  color: var(--color-fg-1);
}

/* The tint shows on the plain page (wallpaper off) with a little more colour than the veil over the photo. */
:root[data-tint] {
  --color-bg: hsl(var(--hue) 22% 94%);
  --color-page: hsl(var(--hue) 40% 92%);
}

@media (prefers-color-scheme: dark) {
  :root[data-tint]:not([data-theme="light"]) {
    --color-bg: hsl(var(--hue) 24% 9%);
    --color-page: hsl(var(--hue) 36% 12%);
  }
}

:root[data-theme="dark"][data-tint] {
  --color-bg: hsl(var(--hue) 24% 9%);
  --color-page: hsl(var(--hue) 36% 12%);
}

.hue {
  display: none;
  -webkit-appearance: none;
  appearance: none;
  /* No tap highlight: on iOS it shows as a white disc around the thumb. */
  -webkit-tap-highlight-color: transparent;
  /* 22 px wider than the visible line, so the thumb's centre can reach both ends of it. */
  width: 94px;
  height: 22px;
  margin: 0 -11px;
  background: linear-gradient(to right, hsl(0 12% 60%), hsl(60 12% 60%), hsl(120 12% 60%), hsl(180 12% 60%), hsl(240 12% 60%), hsl(300 12% 60%), hsl(360 12% 60%)) center / calc(100% - 22px) 2px no-repeat;
  border: none;
  cursor: pointer;
}

.hue::-webkit-slider-runnable-track {
  height: 2px;
  background: transparent;
  border-radius: 1px;
}

/* The thumb is a 22 px target with a small visible dot, so a finger can grab it on a phone. */
.hue::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 22px;
  height: 22px;
  margin-top: -10px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--color-fg-2) 0 4px, transparent 4.5px);
  box-shadow: none;
  border: none;
}

.hue::-moz-range-track {
  height: 2px;
  background: transparent;
}

.hue::-moz-range-thumb {
  width: 22px;
  height: 22px;
  border: none;
  border-radius: 50%;
  background: radial-gradient(circle, var(--color-fg-2) 0 4px, transparent 4.5px);
}

.controls {
  position: absolute;
  left: 24px;
  right: 24px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  bottom: 28px;
  z-index: 1;
  opacity: .8;
  transition: opacity .3s ease-in-out;
  /* The row spans the full width and would otherwise block the footer link. */
  pointer-events: none;
}

.controls button,
.hue {
  pointer-events: auto;
}

/* The wallpaper button stays at the right edge, also when the colour button is hidden and it is the only one left. */
.controls #wallpaper-toggle {
  margin-left: auto;
}

.controls:hover,
.controls:focus-within {
  opacity: .9;
}

.controls button {
  display: block;
  width: 14px;
  height: 14px;
  padding: 0;
  border-radius: 50%;
  overflow: hidden;
  border: 1px solid var(--color-border);
  cursor: pointer;
}

.controls button[aria-pressed="true"] {
  border-color: var(--color-fg-2);
}

.controls span {
  display: block;
  width: 100%;
  height: 100%;
  background-image: url("assets/wallpaper-thumb.jpg");
  background-size: cover;
  background-position: center;
}

/* Landscape phones are short: tighten the column so the quote does not overlap the search bar. */
@media (max-height: 560px) {
  #main {
    transform: none;
  }

  #clock {
    margin-bottom: 20px;
  }

  .links {
    margin-top: 20px;
  }

  .quote {
    bottom: 40px;
    max-width: 560px;
    font-size: 13px;
    line-height: 1.4;
  }
}

/* Phones: lift the controls above the browser's bottom bar and enlarge their touch area. */
@media (max-width: 600px) {
  /* On a phone the quote sits under the AI shortcuts, or under the search when there are none. */
  .centre > .quote {
    position: absolute;
    top: 100%;
    bottom: auto;
    margin-top: 24px;
  }

  .centre > .links:not([hidden]) ~ .quote {
    margin-top: 92px;
  }

  /* As close to the bottom edge as the browser allows: the safe area on iPhone, and the small toolbar. */
  .controls {
    bottom: calc(env(safe-area-inset-bottom, 0px) + 16px);
  }

  /* Phones: footer and controls move above the browser's bottom bar, and stay on one line. */
  footer {
    bottom: calc(env(safe-area-inset-bottom, 0px) + 16px);
  }

  .controls button {
    position: relative;
    margin-left: auto;
  }

  .controls button::before {
    content: "";
    position: absolute;
    inset: -19px;
  }

  /* Short enough to stay clear of the footer text on the narrowest phones. */
  .hue {
    width: 44px;
  }
}

/* AI shortcuts: the list in their window, with move, edit and remove buttons. */
.ai-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
}

.ai-list li {
  display: flex;
  align-items: center;
  gap: 6px;
}

/* A site's own icon is often coloured; the page is monochrome, so it is shown in greys like the built-in icons. */
img.ai-icon {
  filter: grayscale(1);
}

.ai-list .ai-icon {
  display: inline-flex;
  flex: none;
  width: 18px;
  height: 18px;
}

.ai-list .ai-icon svg {
  width: 18px;
  height: 18px;
}

.service-picks {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.service-pick {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  font-size: 13px;
  cursor: pointer;
}

.service-pick:has(input:disabled) {
  opacity: .5;
  cursor: default;
}

.service-pick .ai-icon {
  flex: none;
  width: 18px;
  height: 18px;
}

.service-pick .ai-icon svg {
  width: 18px;
  height: 18px;
}

.ai-list li span {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ai-list button,
.icon-btn {
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  background: none;
  color: var(--color-fg-2);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}

.ai-list button:disabled,
.icon-btn:disabled {
  opacity: .35;
  cursor: default;
}

.ai-list button:focus-visible,
.ai-list button:hover:not(:disabled),
.icon-btn:focus-visible,
.icon-btn:hover:not(:disabled) {
  color: var(--color-fg-1);
}

/* The two icon buttons: a colour button on the left and a background button on the right. Desktop keeps
   the slider and the wallpaper thumbnail, so the icons only show on phones. */
#wallpaper-toggle .glyph {
  display: none;
}

/* On a computer the colour button is a round swatch in the current tint, like the wallpaper thumbnail. */
@media (min-width: 601px) {
  .controls .tint-cycle .glyph {
    display: none;
  }
}

.controls .tint-cycle {
  background: var(--swatch, var(--color-fg-2));
}

.glyph {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.glyph .dot {
  fill: var(--dot, var(--color-fg-2));
  stroke: none;
}

.controls .tint-cycle[hidden] {
  display: none;
}

@media (max-width: 600px) {
  .hue {
    display: none;
  }

  /* The colour button stays on the left; the background button stays on the right. */
  .controls .tint-cycle {
    margin-left: 0;
  }

  .controls .tint-cycle,
  .controls #wallpaper-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    color: var(--color-fg-2);
    background: none;
  }

  .controls #wallpaper-toggle span {
    display: none;
  }

  .controls #wallpaper-toggle .glyph {
    display: block;
  }

  .controls #wallpaper-toggle[aria-pressed="false"] {
    opacity: .45;
  }
}

/* Minimal links: the preview is off, so it stays hidden even on hover. */
.links-preview[hidden] {
  display: none !important;
}

/* Full time: the colons stay still, as on most screen clocks. */
.colon {
  display: inline-block;
}

@media (prefers-reduced-motion: reduce) {
  .wallpaper,
  body,
  .topbar .icon-link,
  .modes button,
  #search,
  #engine,
  .links a {
    transition: none;
  }
}

/* Top bar: colour mode switch and the settings button share the right edge. */
.topright {
  display: flex;
  align-items: center;
  gap: 4px;
}

.settings-button {
  display: flex;
  padding: 6px;
  border-radius: 6px;
  color: var(--color-fg-2);
  transition: color .2s ease-in-out;
}

.settings-button:hover,
.settings-button:focus-visible {
  color: var(--color-fg-1);
}

/* Weather icon: plain on the page, coloured only while the weather button is hovered or focused. */
.weather-icon {
  transition: color .2s ease-in-out;
}

.weather-icon.clear,
.weather-icon.mostly,
.weather-icon.partly {
  --wx: #d9a21b;
}

.weather-icon.cloudy {
  --wx: #7f8fa3;
}

.weather-icon.fog {
  --wx: #9aa0a8;
}

.weather-icon.drizzle,
.weather-icon.rain,
.weather-icon.showers {
  --wx: #3b82c4;
}

.weather-icon.heavyRain,
.weather-icon.heavyShowers {
  --wx: #2f6fb0;
}

.weather-icon.snow,
.weather-icon.heavySnow {
  --wx: #6fa3d6;
}

.weather-icon.storm {
  --wx: #8b6fd6;
}

.weather button:hover .weather-icon,
.weather button:focus-visible .weather-icon {
  color: var(--wx, currentColor);
}

/* Settings: a floating panel over a softened page. */
.settings {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: grid;
  place-items: center;
  padding: 16px;
  background: color-mix(in srgb, var(--color-bg) 70%, transparent);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

.settings[hidden] {
  display: none;
}

.settings-panel {
  width: min(100%, var(--panel-md));
  max-height: 86vh;
  overflow: auto;
  padding: 24px;
  background: var(--color-field);
  border: 1px solid var(--color-border);
  border-radius: 14px;
  color: var(--color-fg-1);
  font-size: 14px;
  line-height: 1.5;
  box-shadow: 0 10px 40px rgba(0, 0, 0, .12);
}

.settings-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
}

.settings-head h2 {
  font-size: 16px;
  font-weight: 600;
}

.settings-close {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  color: var(--color-fg-2);
  font-size: 20px;
  line-height: 1;
}

.settings-close:hover,
.settings-close:focus-visible {
  color: var(--color-fg-1);
}

.settings-hint,
.city-msg {
  font-size: 12px;
  color: var(--color-fg-2);
}

.settings-hint {
  margin: 0 0 16px;
}

.setting {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  cursor: pointer;
}

.setting input {
  accent-color: var(--color-fg-2);
}

.city-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px 0 4px;
}

.city-form > label {
  color: var(--color-fg-2);
  font-size: 12px;
}

.city-row {
  display: flex;
  gap: 8px;
}

#city-input,
#zone-input,
#place-input,
#link-name,
#link-url,
#link-desc,
#ai-name,
#ai-url {
  min-width: 0;
  height: 36px;
  padding: 0 10px;
  background: var(--color-bg);
  color: var(--color-fg-1);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  font: inherit;
}

.lang-select {
  margin-left: auto;
  height: 36px;
  padding: 0 10px;
  background: var(--color-bg);
  color: var(--color-fg-1);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  font: inherit;
}

/* The field beside a button takes the room left; in the link and AI forms the fields keep their height. */
.city-row input {
  flex: 1;
}

/* Buttons beside a field match its height; in the forms they are buttons, not text. */
.city-row .ghost-button {
  height: 36px;
  margin: 0;
  align-self: stretch;
}

.link-form-actions .ghost-button {
  height: 36px;
  margin: 0;
}

.text-button {
  align-self: flex-start;
  padding: 0;
  font-size: 12px;
  color: var(--color-fg-2);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.privacy {
  margin: 2px 0 8px 26px;
  font-size: 12px;
  color: var(--color-fg-2);
}


/* Quote hidden from the settings. */
html[data-quote-off] #quote {
  display: none;
}

/* Full forecast: opens when the weather is clicked. */
.forecast-panel {
  width: min(100%, var(--panel-md));
}

.forecast-now {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 0;
}

.forecast-icon .weather-icon {
  width: 28px;
  height: 28px;
  color: var(--wx);
}

.forecast-temp {
  font-size: 30px;
  font-weight: 400;
  line-height: 1;
}

.forecast-word {
  color: var(--color-fg-2);
}

.forecast-meta {
  margin-top: 6px;
  font-size: 12px;
  color: var(--color-fg-2);
}

.forecast-section {
  margin-top: 16px;
}

.forecast-section h3 {
  margin-bottom: 4px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--color-fg-2);
}

.forecast-row {
  display: grid;
  grid-template-columns: 1.2fr .8fr .8fr 1fr;
  gap: 12px;
  align-items: center;
  padding: 2px 0;
  line-height: 1.3;
  border-bottom: 1px solid var(--color-border);
  font-variant-numeric: tabular-nums;
}

.forecast-row:last-child {
  border-bottom: none;
}

.forecast-day {
  grid-template-columns: 1.4fr auto 1fr 1fr;
}

.forecast-day .forecast-icon .weather-icon {
  width: 18px;
  height: 18px;
}

.forecast-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--color-border);
}

/* The count of extra places, after the chips in the forecast. */
.forecast-foot .ghost-button {
  flex: none;
  margin: 0;
}

.forecast-foot .forecast-link {
  min-width: 0;
  margin-top: 0;
}

.forecast-link {
  display: inline-block;
  font-size: 12px;
  color: var(--color-fg-2);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.forecast-link:hover,
.forecast-link:focus-visible {
  color: var(--color-fg-1);
}

.forecast-head {
  padding-top: 0;
  font-size: 11px;
  color: var(--color-fg-2);
}

/* Weather off: a faint icon in the top bar, so the feature is still there to find. */
.weather button[hidden] {
  display: none;
}

.weather button.idle {
  opacity: .45;
}

.weather button.idle:hover,
.weather button.idle:focus-visible {
  opacity: 1;
}

/* Time zones: a small globe after the date, and a window with the chosen zones. */
.zones-button {
  display: flex;
  margin: 2px auto 0;
  padding: 4px;
  color: var(--color-fg-2);
  opacity: .6;
  transition: opacity .2s ease-in-out, color .2s ease-in-out;
}

.zones-button:hover,
.zones-button:focus-visible {
  color: var(--color-fg-1);
  opacity: 1;
}

.zones-button[hidden] {
  display: none;
}

.zones-panel {
  width: min(100%, 420px);
}

.zones-local,
.zones-empty {
  font-size: 12px;
  color: var(--color-fg-2);
}

#zones-local-window {
  margin: 0 0 8px;
}

.zone-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 7ch 6ch 1fr auto;
  gap: 12px;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--color-border);
  font-variant-numeric: tabular-nums;
}

.zone-day {
  font-size: 12px;
  color: var(--color-fg-2);
}

.zone-remove {
  width: 24px;
  height: 24px;
  border-radius: 6px;
  color: var(--color-fg-2);
  font-size: 16px;
  line-height: 1;
}

.zone-remove:hover,
.zone-remove:focus-visible {
  color: var(--color-fg-1);
}

/* The globe sits above the time, out of the layout, so nothing else moves.
   Its preview opens upwards, into the empty space above the clock. */
#clock {
  position: relative;
}

.zones-wrap {
  position: absolute;
  left: 50%;
  bottom: 100%;
  transform: translateX(-50%);
  margin-bottom: 4px;
  display: flex;
  align-items: center;
}

.zones-preview {
  display: none;
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-bottom: 8px;
  min-width: 300px;
  padding: 12px 14px;
  background: var(--color-field);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  color: var(--color-fg-1);
  font-size: 12px;
  line-height: 1.7;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
  z-index: 2;
}

.zones-preview:empty {
  display: none !important;
}

.zones-preview::before {
  content: "";
  position: absolute;
  bottom: -8px;
  left: 0;
  right: 0;
  height: 8px;
}

/* Previews open on hover with a mouse. A touch screen keeps the hover after a tap, so there the tap opens the panel instead. */
@media (hover: hover) and (pointer: fine) {
  .zones-wrap:hover .zones-preview {
    display: block;
  }
}

.zones-button:focus-visible ~ .zones-preview {
  display: block;
}

/* Options that belong to the weather sit under it, indented, and grey out while it is off. */
.weather-sub {
  margin-left: 24px;
}

.setting:has(input:disabled) {
  /* Dimmed but still readable: about 6:1 against the panel, where half opacity fell under 3:1. */
  opacity: .7;
  cursor: default;
}


.location-title {
  margin-top: 16px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--color-fg-2);
}

/* Condition icons inside the pop-ups: small, next to the hour or the current state. */
.hour-cell,
.now-cell {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.hour-cell .weather-icon {
  width: 12px;
  height: 12px;
}

.now-cell .weather-icon {
  width: 16px;
  height: 16px;
}

/* In the hover preview the icons take their colour on hover, like the top bar. */
.weather:hover .weather-detail .weather-icon,
.weather-detail .weather-icon:hover {
  color: var(--wx, currentColor);
}

/* The full forecast is a deliberate view, so its icons keep their colour. */
.forecast-row .weather-icon {
  color: var(--wx);
}

/* Links: a button in the top left, a hover list, and a window with the full list. */
.links-wrap {
  position: relative;
  display: flex;
}

.links-button {
  position: relative;
}

/* The Wikipedia logo in the button (when own links are off) is sized like the globe it replaces. */
.links-button svg {
  width: 16px;
  height: 16px;
}

.links-preview {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  margin-top: 8px;
  min-width: 240px;
  max-width: 320px;
  max-height: 60vh;
  overflow: auto;
  padding: 10px 12px;
  background: var(--color-field);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  font-size: 12px;
  z-index: 2;
}

.links-preview:empty {
  display: none !important;
}

.links-preview::before {
  content: "";
  position: absolute;
  top: -8px;
  left: 0;
  right: 0;
  height: 8px;
}

.links-button:focus-visible ~ .links-preview {
  display: block;
}

@media (hover: hover) and (pointer: fine) {
  .links-wrap:hover .links-preview {
    display: block;
  }
}

.link-main {
  display: flex;
  flex-direction: column;
  color: var(--color-fg-1);
}

.link-main small {
  font-size: 11px;
  color: var(--color-fg-2);
}

.links-preview .link-main {
  padding: 4px 0;
}

/* Advanced and Manage sit side by side under the presets. */
.settings-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 12px;
}

.settings-actions button {
  margin-top: 16px;
}

/* The tabs of the manage panel; the active one is underlined. */
.manage-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--color-border);
}

.manage-tab-button {
  padding: 6px 0 8px;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  color: var(--color-fg-2);
  font-size: 13px;
  cursor: pointer;
}

.manage-tab-button[aria-selected="true"] {
  color: var(--color-fg-1);
  border-bottom-color: var(--color-fg-2);
}

/* Export and import at the foot of the Data panel, under every tab. */
.manage-io {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--color-border);
}

.manage-section[hidden] {
  display: none;
}

.manage-note {
  margin: 0 0 8px;
  font-size: 12px;
  color: var(--color-fg-2);
}

.place-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.place-list li {
  display: flex;
  align-items: center;
  gap: 6px;
}

.place-list li span {
  flex: 1;
  min-width: 0;
}

.place-list button {
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  background: none;
  color: var(--color-fg-2);
  cursor: pointer;
}

/* The extra places in the forecast window: pick one to see its forecast. */
.forecast-places {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 12px;
}

.forecast-places:empty {
  display: none;
}

.place-chip {
  padding: 4px 10px;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  color: var(--color-fg-2);
  font-size: 12px;
  cursor: pointer;
}

.place-chip[aria-pressed="true"] {
  color: var(--color-fg-1);
  border-color: var(--color-fg-2);
}

.links-list {
  max-height: 40vh;
  overflow: auto;
}

.link-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--color-border);
}

.link-actions {
  display: flex;
  gap: 4px;
}

.row-btn {
  padding: 2px 4px;
  font-size: 12px;
  color: var(--color-fg-2);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.row-btn:hover,
.row-btn:focus-visible {
  color: var(--color-fg-1);
}

.link-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 12px;
}

.link-form > label {
  font-size: 12px;
  color: var(--color-fg-2);
}

.link-form-title {
  font-size: 13px;
  font-weight: 600;
}

.link-form-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 8px;
}

.link-form input:disabled,
.link-form button:disabled {
  opacity: .5;
}

/* Permanent links as a row of icons at the top of the links window. */
.link-icons {
  display: flex;
  gap: 8px;
  padding-bottom: 12px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--color-border);
}

.link-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  color: var(--color-fg-2);
  transition: color .2s ease-in-out, border-color .2s ease-in-out;
}

.link-icon:hover,
.link-icon:focus-visible {
  color: var(--color-fg-1);
  border-color: var(--color-border-hover);
}

/* The hidden attribute must win over the icon-link display rule. */
.links-button[hidden] {
  display: none;
}

/* Time zone lines: name, UTC label, time and day, each in its own column so they line up. */
.zone-tag {
  font-size: 10px;
  letter-spacing: .04em;
  color: var(--color-fg-2);
}

.zone-time {
  text-align: right;
}

.zone-day {
  text-align: right;
}

/* Permanent link logos in the links window: the same size and weight as the other icons. */
.link-icon svg {
  width: 16px;
  height: 16px;
}

/* The Reuters name as a wide icon, so the word stays readable. */
.link-icon svg.wide {
  width: 40px;
  height: 16px;
}

/* Help: the guide from the settings window. */
.help-panel {
  width: min(100%, var(--panel-md));
  /* The title stays put; only the guide below it scrolls, so there is one scrollbar. */
  display: flex;
  flex-direction: column;
  max-height: 86vh;
  overflow: hidden;
}

/* The guide is one column, like the settings: every topic is a block of the same width, so no uneven gaps. */
.help-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
}

/* Each topic has a divider under it, as the advanced groups do; the first row has no space above. */
.help-section {
  padding: 16px 0;
  border-bottom: 1px solid var(--color-border);
}

.help-section:first-child {
  padding-top: 0;
}

.help-section h3 {
  margin: 0 0 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--color-fg-2);
}

.help-link {
  display: inline-block;
  margin-top: 6px;
  font-size: 12px;
  color: var(--color-fg-2);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.help-link:hover,
.help-link:focus-visible {
  color: var(--color-fg-1);
}

.help-section p {
  max-width: 70ch;
  font-size: 13px;
  line-height: 1.6;
  color: var(--color-fg-1);
}

.settings-head .text-button {
  margin-left: auto;
  margin-right: 12px;
}

/* Dialog panels are focused as a whole when they open; the outline is not wanted there. */
.settings-panel:focus {
  outline: none;
}

/* The wallpaper button can be hidden in settings. */
.controls button[hidden] {
  display: none;
}

/* The page presets sit side by side, above the other settings. */
.presets {
  display: flex;
  gap: 18px;
}

.presets .setting {
  padding: 6px 0;
}

/* The IP details window: the address, when it was asked, and the check button. */
.ip-current {
  margin: 12px 0 2px;
  font-size: 22px;
  font-variant-numeric: tabular-nums;
}

.ip-meta {
  margin: 0 0 16px;
  font-size: 13px;
  color: var(--color-fg-2);
}

.settings-panel > .ghost-button {
  margin-top: 16px;
}

.ghost-button {
  align-self: flex-start;
  height: 32px;
  margin: 4px 0 6px;
  padding: 0 14px;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  color: var(--color-fg-1);
  font-size: 13px;
}

.ghost-button:hover,
.ghost-button:focus-visible {
  border-color: var(--color-fg-2);
}

.ghost-button:disabled {
  opacity: .5;
}

.ip-list {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0 16px;
  margin: 0;
}

.ip-list dt,
.ip-list dd {
  padding: 8px 0;
  border-bottom: 1px solid var(--color-border);
}

.ip-list dt {
  opacity: .6;
}

.ip-list dd {
  margin: 0;
  overflow-wrap: anywhere;
}



/* The advanced block sits under the basic view with some air. */
.advanced {
  margin-top: 16px;
}

/* A select in a setting row never grows wider than the row. */
.setting select {
  max-width: 100%;
}

/* The grid below would otherwise override the hidden attribute. */
.advanced[hidden],
.presets[hidden] {
  display: none;
}

/* Advanced: a wider window. The options sit in four groups, two per row, so each group keeps its own column. */

.settings-panel.is-wide {
  width: min(100%, var(--panel-lg));
}

.advanced {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 40px;
  align-items: stretch;
}

.adv-group {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--color-border);
}

.adv-group > .location-title {
  margin-bottom: 4px;
}

.adv-group > .location-title:not(:first-child) {
  margin-top: 14px;
}

/* Advanced and Manage are buttons, not links: they are actions that open more options. */
#advanced-toggle,
#manage-open,
#ip-open {
  align-self: flex-start;
  height: 32px;
  margin: 14px 0 6px;
  padding: 0 14px;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  color: var(--color-fg-1);
  font-size: 13px;
  text-decoration: none;
}

#advanced-toggle:hover,
#advanced-toggle:focus-visible,
#manage-open:hover,
#manage-open:focus-visible,
#ip-open:hover,
#ip-open:focus-visible {
  border-color: var(--color-fg-2);
}

/* The data reset has a short line above its button, so the button says only what it does. */
.reset-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  max-width: 360px;
}

.reset-note {
  margin: 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--color-fg-2);
}

.reset-item .ghost-button {
  margin-top: 6px;
}

/* Action buttons use greys only: a darker grey when something can be done, a lighter, dimmed grey when not.
   Only text buttons with a verb (Save, Add) are "action" buttons; arrows and icons stay as before.
   The counters keep a soft colour: green while there is room, blue with the word "full" at the limit. */

/* At the limit the add field is greyed out and says why, centred in the field. */
input.limit-full:disabled {
  text-align: center;
}

input.limit-full:disabled::placeholder {
  color: #7d9dc4;
  opacity: 1;
}

button.action:not(:disabled) {
  border-color: var(--color-fg-2);
  color: var(--color-fg-1);
}

button.action:disabled {
  border-color: var(--color-border);
  color: var(--color-fg-2);
  opacity: 0.5;
  cursor: default;
}

/* Resetting throws data away: a red heading and red boxes around each reset button. */
.adv-group.reset-group {
  grid-column: 1 / -1;
}

.adv-group.reset-group > .location-title {
  color: #e5484d;
}

.reset-intro {
  margin: 0 0 8px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--color-fg-2);
}

.reset-boxes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
}

/* The two reset buttons carry the red frame themselves, so they are the same height as the other buttons. */
.reset-boxes .danger-button {
  border-color: #e5484d;
  white-space: nowrap;
}

/* The first-visit hint: a small card under the top-right icons, gone after one click. */
.first-hint {
  position: fixed;
  top: 52px;
  right: 16px;
  z-index: 50;
  max-width: 260px;
  padding: 12px 36px 12px 14px;
  border: 1px solid var(--color-border);
  border-radius: 10px;
  background: var(--color-panel, #faf8f4);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
  font-size: 14px;
  line-height: 1.4;
  color: var(--color-fg-1);
}

.first-hint[hidden] {
  display: none;
}

.first-hint-close {
  position: absolute;
  top: 6px;
  right: 10px;
  border: none;
  background: none;
  color: var(--color-fg-2);
  font-size: 16px;
  cursor: pointer;
}

/* The quick start: a short first-use window. The search bar picture is the focus; the red arrow points at the engine icon. */
.quickstart-panel {
  width: min(560px, 100%);
}

.quick-row {
  margin: 14px 0 0;
  font-size: 13px;
}

.quick-link,
.first-hint-link {
  color: inherit;
  text-decoration: underline;
}

.first-hint-link {
  display: inline-block;
  margin-top: 6px;
  font-size: 13px;
}

.quick-head {
  margin: 16px 0 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-fg-2);
}

.quick-shot {
  padding: 56px 12px 12px;
  border-radius: 14px;
  background: rgba(127, 127, 127, 0.1);
}

.quick-shot-img {
  position: relative;
}

.quick-shot-img img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 12px;
}

.quick-arrow {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  fill: none;
  stroke: #e5484d;
  stroke-width: 1.3;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-opacity: 0.8;
}

.quick-tag {
  fill: var(--color-fg-1);
  stroke: none;
  stroke-opacity: 1;
}

#quickstart-click {
  font-size: 11px;
  font-weight: 600;
  fill: var(--color-panel, #faf8f4);
  stroke: none;
  stroke-opacity: 1;
}

.quick-text {
  margin: 10px 2px 0;
}

.quick-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.quick-card {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 12px;
  border-radius: 12px;
  background: rgba(127, 127, 127, 0.1);
  font-size: 13px;
  line-height: 1.4;
}

.quick-card b {
  font-size: 14px;
}

.quick-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-top: 16px;
}

.quick-note {
  font-size: 12px;
  color: var(--color-fg-2);
}

@media (max-width: 600px) {
  .quick-cards {
    grid-template-columns: 1fr;
  }
}

/* Version and last update, bottom right of the settings panel. */
.app-version {
  margin: 20px 0 0;
  text-align: right;
  font-size: 11px;
  color: var(--color-fg-2);
}

.app-version a {
  color: inherit;
  text-decoration: underline;
}

/* Long labels wrap inside the button instead of spilling over its border. */
.adv-group .ghost-button {
  height: auto;
  min-height: 32px;
  padding: 6px 14px;
  line-height: 1.3;
  text-align: left;
}

/* Phones: the advanced settings use two columns for the short checkbox groups, and a select group takes the full width.
   The help stays in one column. */
@media (max-width: 600px) {
  .advanced {
    grid-template-columns: 1fr 1fr;
    gap: 4px 16px;
  }

  .adv-group:has(select),
  .adv-group:has(#city-form) {
    grid-column: 1 / -1;
  }

  /* The place field takes the row; Save stays beside it. */
  .city-row {
    width: 100%;
  }

  .city-row input {
    flex: 1 1 auto;
    min-width: 0;
    width: auto;
  }

  .city-row .ghost-button {
    flex: none;
  }

  .setting select {
    max-width: 100%;
    min-width: 0;
  }

  .setting {
    min-width: 0;
  }

  .settings-panel.is-wide,
  .help-panel {
    width: 100%;
  }

  .settings-panel {
    max-height: 90vh;
  }

  .help-panel {
    max-height: 90vh;
  }

  .help-section p,
  .privacy {
    font-size: 14px;
  }

  .help-section {
    padding-top: 16px;
  }

  .help-section:first-child {
    padding-top: 0;
  }
}

/* The links and time zones windows: a short list plus a way to the full manage panel. */
/* The links window: the permanent icons, the visitor's own links, and a way to the full manage panel. */
.links-own {
  margin: 12px 0 0;
}

.own-link {
  display: block;
  padding: 8px 0;
  border-bottom: 1px solid var(--color-border);
  color: var(--color-fg-1);
  text-decoration: none;
}

.own-link:hover,
.own-link:focus-visible {
  color: var(--color-fg-2);
}

.own-desc {
  display: block;
  font-size: 12px;
  color: var(--color-fg-2);
}

/* On a phone every window has the same inner gutter; the desktop gutter is 24 px. The forecast is the one
   window that must fit without scrolling, so its sections sit a little closer on a phone. */
@media (max-width: 600px) {
  .settings-panel {
    padding: 18px;
  }

  .forecast-section {
    margin-top: 10px;
  }

  .forecast-foot {
    margin-top: 10px;
    padding-top: 10px;
  }

  .forecast-row {
    padding: 1px 0;
  }
}

/* Data beheren, the background tab: one row per wallpaper with a swatch, its name and a switch. */
.wallpaper-row {
  position: relative;
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--color-border);
}


.wallpaper-names {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.wallpaper-credit {
  justify-self: start;
  font-size: 12px;
  color: var(--color-fg-2);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.wallpaper-credit:hover,
.wallpaper-credit:focus-visible {
  color: var(--color-fg-1);
}

.wallpaper-swatch {
  width: 40px;
  height: 28px;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  background-size: cover;
  background-position: center;
}

/* Hovering a swatch shows the wallpaper larger beside it. It only appears over the swatch, so the name and links stay clickable. */
.wallpaper-swatch {
  position: relative;
  z-index: 2;
}

.wallpaper-swatch::after {
  content: '';
  position: absolute;
  left: calc(100% + 12px);
  top: 50%;
  width: 200px;
  height: 112px;
  transform: translateY(-50%);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  background: var(--preview) center / cover no-repeat;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .18);
  opacity: 0;
  pointer-events: none;
  transition: opacity .15s ease;
}

.wallpaper-swatch:hover::after {
  opacity: 1;
}

.wallpaper-switch {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
}
