/* Breezy Weather - design system
   Tokens first, then primitives, then components.
   Proportions follow the original v1 layout: 64rem shell, 1.5rem card
   radius, 1.5rem card padding, glass at 14% white. */

/* ============================================================
   1. TOKENS
   ============================================================ */

:root {
  --sky-1: #38bdf8;
  --sky-2: #2563eb;
  --sky-3: #4338ca;

  --glass-bg: rgba(255, 255, 255, 0.14);
  --glass-bg-soft: rgba(255, 255, 255, 0.10);
  --glass-bg-hover: rgba(255, 255, 255, 0.22);
  --glass-border: rgba(255, 255, 255, 0.16);
  --glass-blur: 18px;

  --shadow-sm: 0 2px 8px rgba(8, 15, 40, 0.16);
  --shadow-md: 0 10px 30px rgba(8, 15, 40, 0.25);
  --shadow-lg: 0 20px 55px rgba(8, 15, 40, 0.34);

  --ink: #ffffff;
  --ink-soft: rgba(255, 255, 255, 0.82);
  --ink-faint: rgba(255, 255, 255, 0.60);

  --sev-extreme: #ff5b6e;
  --sev-severe: #ff9447;
  --sev-moderate: #ffd24a;
  --sev-minor: #7ddfff;
  --ok: #5ce1a6;

  --r-sm: 0.75rem;
  --r-md: 1rem;
  --r-lg: 1.5rem;
  --r-pill: 999px;

  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.5rem;
  --sp-6: 2rem;

  --font: ui-rounded, "SF Pro Rounded", "SF Pro Display", Inter, system-ui,
    -apple-system, "Segoe UI", Roboto, sans-serif;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --dur: 220ms;

  --maxw: 64rem;
  --card-pad: 1.5rem;
}

[data-contrast="high"] {
  --glass-bg: rgba(6, 12, 32, 0.72);
  --glass-bg-soft: rgba(6, 12, 32, 0.62);
  --glass-bg-hover: rgba(6, 12, 32, 0.82);
  --glass-border: rgba(255, 255, 255, 0.32);
  --ink-soft: rgba(255, 255, 255, 0.92);
  --ink-faint: rgba(255, 255, 255, 0.78);
}

/* ============================================================
   2. RESET AND BASE
   ============================================================ */

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

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

body {
  margin: 0;
  min-height: 100svh;
  font-family: var(--font);
  color: var(--ink);
  background: #0b1a3f;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  display: block;
}

/* -webkit-appearance: none is mandatory for Safari and iOS. Without it,
   Safari paints its own native control chrome over buttons and search
   inputs, which overrides the background and washes the label out. The GPS
   button rendered as a plain light pill with barely visible text because
   of this, and no amount of background tweaking would have fixed it. */
/* Every control inherits typography. */
button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

/* Strip native chrome from buttons and text fields ONLY. Applying this to
   every input also erased checkboxes, which have no styling of their own to
   fall back on, so the alert settings had invisible tick boxes. */
button,
input[type="text"],
input[type="search"],
input[type="email"],
input[type="password"],
input[type="number"],
textarea {
  -webkit-appearance: none;
  appearance: none;
  border-radius: 0;
}

button {
  cursor: pointer;
  border: 0;
  background: none;
}

/* Safari also draws its own clear button and inset shape on search fields. */
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-results-button,
input[type="search"]::-webkit-search-results-decoration {
  -webkit-appearance: none;
  display: none;
}

a {
  color: inherit;
}

h1,
h2,
h3,
p,
dl,
dd,
dt {
  margin: 0;
}

::selection {
  background: rgba(255, 255, 255, 0.24);
}

:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
  border-radius: 6px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translate(-50%, -120%);
  z-index: 200;
  padding: 0.7rem 1.2rem;
  background: #fff;
  color: #0b1a3f;
  border-radius: 0 0 var(--r-md) var(--r-md);
  font-weight: 600;
  text-decoration: none;
  transition: transform var(--dur) var(--ease);
}

.skip-link:focus {
  transform: translate(-50%, 0);
}

/* ============================================================
   3. SKY
   ============================================================ */

.sky {
  position: fixed;
  inset: 0;
  z-index: -2;
  background: linear-gradient(160deg, var(--sky-1) 0%, var(--sky-2) 50%, var(--sky-3) 100%);
  transition: background 900ms var(--ease);
}

.sky::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(46rem 30rem at 76% 6%, rgba(255, 255, 255, 0.20), transparent 62%);
}

.grain {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.22;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.4'/%3E%3C/svg%3E");
}

/* ============================================================
   4. GLASS
   ============================================================ */

/* Flat translucency, no diagonal sheen. The sheen looked fine on a large
   card and like a smudge on the search bar, so it is gone entirely. */
.glass {
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md), inset 0 1px 0 rgba(255, 255, 255, 0.16);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(150%);
  backdrop-filter: blur(var(--glass-blur)) saturate(150%);
}

/* ============================================================
   5. LAYOUT
   ============================================================ */

/* Safe-area insets matter once this is installed to a home screen. On a
   notched iPhone in standalone mode there is no browser chrome, so content
   would otherwise slide under the notch and the home indicator. */
.shell {
  --shell-x: var(--sp-4);
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-top: calc(var(--sp-5) + env(safe-area-inset-top, 0px));
  padding-bottom: calc(var(--sp-6) + env(safe-area-inset-bottom, 0px));
  padding-left: max(var(--shell-x), env(safe-area-inset-left, 0px));
  padding-right: max(var(--shell-x), env(safe-area-inset-right, 0px));
}

@media (min-width: 640px) {
  .shell {
    --shell-x: var(--sp-5);
  }
}

/* scroll-margin keeps a jumped-to heading clear of the sticky jump nav.
   Roughly bar height plus its top offset plus a little air. Without it the
   title parks underneath the bar and the section looks like it starts at
   its second line. Applies to the alert banner's scrollIntoView too. */
.section {
  margin-top: var(--sp-5);
  scroll-margin-top: 3.75rem;
}

.section--tight {
  margin-top: var(--sp-4);
}

.section__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
  padding-inline: var(--sp-1);
}

.section__title {
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: 0.005em;
}

.section__note {
  font-size: 0.8125rem;
  color: var(--ink-faint);
}

/* ============================================================
   6. HEADER AND BUTTONS
   ============================================================ */

.masthead {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-4);
}

.masthead__logo {
  height: 8rem;
  width: auto;
  user-select: none;
}

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
}

/* Matches v1 exactly: 0.75rem horizontal / 0.5rem vertical padding,
   0.875rem text, 1rem radius, 0.5rem gap. Sized by its padding rather
   than a fixed height, so every pill grows with its own label instead of
   being squeezed into one box. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem 0.75rem;
  border-radius: var(--r-md);
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.25rem;
  white-space: nowrap;
  text-decoration: none;
  transition: background var(--dur) var(--ease), transform 120ms var(--ease);
}

/* Toolbar pills get a shared minimum so a short label like degrees F
   still reads as the same control as Profile beside it. */
.toolbar .btn {
  min-width: 4.25rem;
}

.btn:hover {
  background: var(--glass-bg-hover);
}

.btn:active {
  transform: scale(0.97);
}

.btn--primary {
  background: #fff;
  color: #16255a;
  border-color: #fff;
  font-weight: 600;
}

.btn--primary:hover {
  background: rgba(255, 255, 255, 0.88);
}

.btn--quiet {
  background: rgba(255, 255, 255, 0.16);
}

/* Safari fix. A backdrop-filter inside another backdrop-filter samples the
   already-blurred parent, and the two compound until the button washes out
   to near white with white text on it. The GPS button was effectively
   invisible. Buttons sitting inside a glass panel drop their own blur and
   use a solid enough tint instead. */
.glass .btn,
.search__bar .btn {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.search__bar .btn--quiet {
  background: rgba(255, 255, 255, 0.26);
  border-color: rgba(255, 255, 255, 0.30);
  color: #fff;
}

.search__bar .btn--quiet:hover {
  background: rgba(255, 255, 255, 0.38);
}

.btn[aria-pressed="true"] {
  background: rgba(255, 255, 255, 0.30);
}

/* ============================================================
   6b. JUMP NAV
   ============================================================ */

/* Sticks under the top of the viewport once you scroll past it, so you can
   move between sections from anywhere on the page.

   z-index 50 puts it over the rail arrows (20) so those never punch through
   the bar, and under the search suggestions (60) so the dropdown still sits
   on top when it opens. */
.jumpnav {
  position: sticky;
  top: calc(var(--sp-2) + env(safe-area-inset-top, 0px));
  z-index: 50;
  margin-top: var(--sp-4);
  display: flex;
  justify-content: center;
}

/* Hugs its own labels rather than stretching the full shell width. A full
   width bar with the links centred inside leaves a dead gutter at each end
   and reads as broken.

   Scrolls sideways rather than wrapping to a second row. A bar that grows
   taller as labels appear would shove the page down every time Rain or
   Favorites shows up. */
.jumpnav__track {
  display: flex;
  align-items: center;
  gap: 0.125rem;
  max-width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  padding: 0.25rem;
  border-radius: var(--r-pill);
  background: var(--glass-bg-soft);
  border: 1px solid var(--glass-border);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(150%);
  backdrop-filter: blur(var(--glass-blur)) saturate(150%);
}

.jumpnav__track::-webkit-scrollbar {
  display: none;
}

.jumpnav__link {
  flex: 0 0 auto;
  padding: 0.35rem 0.7rem;
  border-radius: var(--r-pill);
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.1rem;
  white-space: nowrap;
  color: var(--ink-faint);
  text-decoration: none;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.jumpnav__link:hover {
  background: var(--glass-bg-hover);
  color: var(--ink);
}

.jumpnav__link:active {
  transform: scale(0.97);
}

/* Set by js/jumpnav.js as you scroll. Solid white rather than another
   translucent layer: a white tint stacked on the already translucent bar
   came out muddy grey instead of reading as selected. */
.jumpnav__link[aria-current="true"] {
  background: #fff;
  color: #16255a;
  font-weight: 600;
}

/* ============================================================
   7. SEARCH
   ============================================================ */

.search {
  position: relative;
  margin-top: var(--sp-4);
}

.search__bar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 0.5rem;
}

.search__icon {
  flex: none;
  display: grid;
  place-items: center;
  margin-left: 0.5rem;
  opacity: 0.75;
}

.search__input {
  flex: 1;
  min-width: 0;
  height: 2.375rem;
  padding: 0 0.25rem;
  background: none;
  border: 0;
  outline: none;
  font-size: 1rem;
}

.search__input::placeholder {
  color: var(--ink-faint);
}

.suggest {
  position: absolute;
  z-index: 60;
  left: 0;
  right: 0;
  top: calc(100% + 0.5rem);
  padding: 0.4rem;
  border-radius: var(--r-md);
  max-height: 19rem;
  overflow-y: auto;
  list-style: none;
  margin: 0;
}

.suggest[hidden] {
  display: none;
}

.suggest__item {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  padding: 0.55rem 0.7rem;
  border-radius: var(--r-sm);
  cursor: pointer;
  font-size: 0.9375rem;
}

.suggest__item:hover,
.suggest__item[aria-selected="true"] {
  background: rgba(255, 255, 255, 0.18);
}

.suggest__region {
  font-size: 0.8125rem;
  color: var(--ink-faint);
}

.hint {
  margin-top: var(--sp-2);
  padding-inline: var(--sp-1);
  font-size: 0.8125rem;
  color: var(--ink-soft);
}

/* ============================================================
   8. CURRENT CONDITIONS
   ============================================================ */

/* The hero is the anchor. Its two rows of text come to about 248px, and
   the wind card is built to come in just under that, so the hero sets the
   height and the wind card fills it. That is the opposite of before, when
   three stacked tiles made the wind card 60px taller and the hero had
   space it could not use. */
.current {
  display: grid;
  gap: var(--sp-4);
  align-items: stretch;
}

/* Title on its own row, card taking whatever is left. Both columns get the
   same title height, so the two cards start and end on the same lines. */
.current__col {
  display: grid;
  grid-template-rows: auto 1fr;
  min-width: 0;
}

/* 1.15fr rather than 1.6fr. The hero's content is only about 350px wide,
   so at the old ratio it carried 214px of unused width while the wind card
   was squeezed. This hands that space to the card that can use it. */
@media (min-width: 880px) {
  .current {
    grid-template-columns: 1.15fr 1fr;
  }
}

/* Flex so now__grid can take the card's full height and push the stats row
   to the floor. */
.now {
  display: flex;
  padding: var(--card-pad);
}

.now__grid {
  flex: 1;
}

.now__top {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}

.now__city {
  font-size: clamp(1.75rem, 4.2vw, 2.25rem);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.now__region,
.now__date {
  margin-top: 0.15rem;
  font-size: 0.9375rem;
  color: var(--ink-soft);
}

.fav-toggle {
  flex: none;
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  font-size: 1.5rem;
  line-height: 1;
  border-radius: 50%;
  color: var(--ink);
  transition: transform 160ms var(--ease), background var(--dur) var(--ease);
}

.fav-toggle:hover {
  background: rgba(255, 255, 255, 0.16);
}

.fav-toggle:active {
  transform: scale(0.88);
}

.fav-toggle[aria-pressed="true"] {
  color: #ff8095;
}

/* City and emoji on top, temperature and readings beneath.
   The columns are 1fr then auto, NOT auto then 1fr. That order is the whole
   fix: the flexible column holds the city name, so "Kokomo" and "Palawan
   Island" both just absorb slack instead of forcing the emoji sideways.
   Getting it backwards is what tore the card apart. */
/* Three bands: who and what, the temperature, then the readings on the
   floor of the card.

   The card stretches to match the wind card beside it, so any leftover
   height has to go somewhere. Centring everything sent all of it into one
   gap in the middle of the card. A full height grid with the stats row
   last spreads it across the seams instead, where it reads as air. */
.now__grid {
  display: grid;
  height: 100%;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "city     emoji"
    "reading  reading"
    "stats    stats";
  column-gap: var(--sp-5);
  row-gap: var(--sp-4);
  align-items: start;
}

/* Temperature and condition share a baseline rather than stacking. */
.now__reading {
  grid-area: reading;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0 var(--sp-3);
  align-self: center;
  min-width: 0;
}

.now__stats {
  grid-area: stats;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-2);
}

.now__head {
  grid-area: city;
  align-self: start;
  min-width: 0;
}

.now__emoji {
  grid-area: emoji;
  justify-self: center;
}

.now__temp {
  grid-area: temp;
}


/* Long place names wrap rather than stretching the card. */
.now__city {
  overflow-wrap: anywhere;
}

/* Single column on small screens, everything centred. */
@media (max-width: 560px) {
  .now__grid {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto 1fr auto;
    grid-template-areas:
      "city"
      "emoji"
      "reading"
      "stats";
    justify-items: center;
    row-gap: var(--sp-3);
  }
  .now__head,
  .now__stats {
    justify-self: stretch;
  }
  .now__reading {
    justify-content: center;
  }
}

/* Dial column is flexible, tile column is a fixed 11.5rem so the tiles come
   out the same size as the ones in A Closer Look rather than stretching to
   whatever is left over. */
.windcard {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 11.5rem;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--card-pad);
}

.windcard__dial {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
}

/* 17vw so the dial reaches its ceiling at normal laptop widths rather than
   staying small and leaving the card short of the hero beside it. */
.windcard .compass {
  width: clamp(8rem, 17vw, 10.5rem);
  height: clamp(8rem, 17vw, 10.5rem);
}

.windcard__mood {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-faint);
  text-align: center;
}

/* Same tile component, laid out for a tall narrow column instead of a wide
   short row: emoji and label on the left, value on the right. Stacking
   them vertically made each tile 80px and the card 60px taller than the
   hero. As rows they are 43px, so the card fits inside the hero's height
   and the dial has room to breathe. Colours, radius, type and emoji are
   unchanged, so it still reads as the same component. */
.windcard__tiles {
  display: grid;
  grid-auto-rows: 1fr;
  align-content: center;
  gap: var(--sp-2);
}

.windcard__tiles .detail {
  flex-direction: row;
  align-items: center;
  gap: 0.55rem;
  padding: 0.6rem 0.8rem;
  text-align: left;
}

.windcard__tiles .detail__label {
  flex: 1;
  min-width: 0;
}

.windcard__tiles .detail__value {
  font-size: 1.0625rem;
  white-space: nowrap;
}

/* Between the stacking point and the two-column point the wind card runs
   full width, so the tile column can be wider without looking stranded. */
@media (max-width: 879px) {
  .windcard {
    grid-template-columns: minmax(0, 1fr) minmax(11.5rem, 20rem);
  }
}

/* Narrow phones: dial on top, readings beneath it as full width rows. */
@media (max-width: 560px) {
  .windcard {
    grid-template-columns: minmax(0, 1fr);
    justify-items: stretch;
    gap: var(--sp-3);
  }
  .windcard__dial {
    justify-self: center;
  }
  .windcard__tiles {
    width: 100%;
  }
}

.now__temp {
  font-size: clamp(3.8rem, 7.6vw, 6rem);
  font-weight: 400;
  line-height: 0.9;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.now__emoji {
  font-size: clamp(3.2rem, 6vw, 4.75rem);
  line-height: 1;
}

/* Sits on the temperature's baseline rather than over the readings. */
.now__summary {
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.2;
}

/* ============================================================
   9. COMPASS
   ============================================================ */

/* The readout sits under the dial. It used to be layered on top of the
   needle and hub, which is why the text collided with them. */
/* Reads as a domed glass dial: light source top left, a rim highlight,
   and a soft shadow pooling at the bottom inside edge. */
.compass {
  position: relative;
  width: 9.5rem;
  height: 9.5rem;
  border-radius: 50%;
  background:
    radial-gradient(
      circle at 32% 26%,
      rgba(255, 255, 255, 0.34) 0%,
      rgba(255, 255, 255, 0.12) 34%,
      rgba(255, 255, 255, 0.04) 58%,
      rgba(0, 0, 0, 0.06) 100%
    );
  border: 1px solid rgba(255, 255, 255, 0.22);
  box-shadow:
    0 10px 24px rgba(8, 15, 40, 0.22),
    inset 0 2px 5px rgba(255, 255, 255, 0.34),
    inset 0 -8px 18px rgba(0, 0, 0, 0.16),
    inset 0 0 0 1px rgba(255, 255, 255, 0.06);
}

/* Bezel ring, kept hairline and pushed right out to the rim so the dial
   face stays full size and the N/E/S/W letters sit clear inside it. */
.compass::after {
  content: "";
  position: absolute;
  inset: 0.2rem;
  border-radius: 50%;
  pointer-events: none;
  border: 1px solid rgba(255, 255, 255, 0.09);
  box-shadow: inset 0 2px 10px rgba(0, 0, 0, 0.12);
}

.compass__tick {
  position: absolute;
  z-index: 4;
  display: grid;
  place-items: center;
  width: 1.4rem;
  height: 1.4rem;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--ink-soft);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
}

/* Letters sit just inside the hairline ring, close to the rim like a
   real dial, with clearance on both sides. */
.compass__tick--n { top: 0.5rem; left: 50%; transform: translateX(-50%); }
.compass__tick--e { right: 0.5rem; top: 50%; transform: translateY(-50%); }
.compass__tick--s { bottom: 0.5rem; left: 50%; transform: translateX(-50%); }
.compass__tick--w { left: 0.5rem; top: 50%; transform: translateY(-50%); }

.compass__needle {
  position: absolute;
  z-index: 2;
  left: 50%;
  top: 50%;
  width: 0.25rem;
  /* Stops short of the letters at every angle as it rotates. */
  height: 30%;
  transform-origin: bottom center;
  transform: translate(-50%, -100%) rotate(0deg);
  transition: transform 700ms var(--ease);
  border-radius: var(--r-pill);
  background: linear-gradient(to top, rgba(255, 255, 255, 0.35), #fff);
  box-shadow: 0 0 10px rgba(255, 255, 255, 0.45);
}

.compass__hub {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 3;
  width: 0.85rem;
  height: 0.85rem;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(
    circle at 34% 30%,
    rgba(255, 255, 255, 0.95),
    rgba(255, 255, 255, 0.34) 70%
  );
  border: 1px solid rgba(255, 255, 255, 0.5);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.28);
}

/* ============================================================
   11. DETAIL STRIP
   ============================================================ */

/* Ten readings. Ten divides evenly by five and by two and nothing else
   useful, so those are the only two column counts that avoid an orphan
   tile on the last row. */
.details {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--sp-3);
  padding: var(--sp-4);
}

@media (max-width: 620px) {
  .details {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.detail {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1rem;
  padding: 0.7rem 0.5rem;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, 0.09);
  text-align: center;
}

.detail__emoji {
  font-size: 1.35rem;
  line-height: 1.2;
}

.detail__label {
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.detail__value {
  font-size: 1.125rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.detail__value--sm {
  font-size: 0.9375rem;
}

.detail__band {
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
}

/* ============================================================
   12. ALERTS
   ============================================================ */

.alert-banner {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  margin-top: var(--sp-4);
  padding: 0.85rem var(--sp-4);
  border-radius: var(--r-md);
  border: 1px solid rgba(255, 91, 110, 0.7);
  background: rgba(255, 91, 110, 0.18);
  color: var(--ink);
  font-size: 0.9375rem;
  font-weight: 600;
  text-align: left;
}

.alert-banner[hidden] {
  display: none;
}

.alert-banner__text {
  flex: 1;
  min-width: 0;
}

.alert-banner__go {
  font-size: 0.8125rem;
  font-weight: 600;
  opacity: 0.85;
  text-decoration: underline;
}

/* Reassuring, not alarming. This is the state people see almost every day,
   so it should read as a clean bill of health rather than an empty box. */
.alerts-empty {
  padding: var(--sp-5) var(--sp-4);
  text-align: center;
}

.alerts-empty__mark {
  font-size: 1.75rem;
  line-height: 1;
  margin-bottom: var(--sp-2);
}

.alerts-empty__title {
  font-size: 1.0625rem;
  font-weight: 600;
}

.alerts-empty__note {
  max-width: 34rem;
  margin: var(--sp-2) auto 0;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--ink-soft);
}

.alerts-empty--error .alerts-empty__title {
  color: var(--sev-severe);
}

.alerts-empty__link {
  display: inline-block;
  margin-top: var(--sp-3);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.4);
  padding-bottom: 1px;
}

.alerts-empty__link:hover {
  border-bottom-color: #fff;
}

.alert-card {
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
}

.alert-card:last-child {
  border-bottom: 0;
}

.alert-card__top {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
}

.alert-card__title {
  flex: 1;
  min-width: 12rem;
  font-size: 1.0625rem;
  font-weight: 600;
}

.sev-badge {
  padding: 0.2rem 0.6rem;
  border-radius: var(--r-pill);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #16255a;
  background: var(--ink-faint);
}

.sev-badge[data-sev="Extreme"] { background: var(--sev-extreme); }
.sev-badge[data-sev="Severe"] { background: var(--sev-severe); }
.sev-badge[data-sev="Moderate"] { background: var(--sev-moderate); }
.sev-badge[data-sev="Minor"] { background: var(--sev-minor); }

.alert-card__when {
  margin-top: var(--sp-2);
  font-size: 0.8125rem;
  color: var(--ink-faint);
}

.alert-card__body {
  margin-top: var(--sp-3);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ink-soft);
  white-space: pre-line;
  max-height: 9rem;
  overflow: hidden;
}

.alert-card__body--open {
  max-height: none;
}

.alert-card__more {
  margin-top: var(--sp-2);
  font-size: 0.8125rem;
  font-weight: 600;
  text-decoration: underline;
  color: var(--ink-soft);
}

.alert-card__action {
  margin-top: var(--sp-3);
  padding: var(--sp-3);
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, 0.10);
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.55;
  white-space: pre-line;
}

/* ============================================================
   13. RAILS, HOURLY, FAVORITES
   ============================================================ */

.rail {
  position: relative;
}

.rail__track {
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-4);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  -ms-overflow-style: none;
  overscroll-behavior-x: contain;
}

.rail__track::-webkit-scrollbar {
  display: none;
}

.rail__btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 20;
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.24);
  border: 1px solid var(--glass-border);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  transition: opacity var(--dur) var(--ease), background var(--dur) var(--ease);
}

/* Inside the panel, same as v1. Negative offsets hung them off the edge. */
.rail__btn--prev { left: 0.5rem; }
.rail__btn--next { right: 0.5rem; }

/* Geometry, not a font glyph. Text arrows sit wherever the typeface puts
   them relative to the baseline, so they read as bottom-heavy and shift
   between devices. An SVG is centred by its viewBox everywhere. */
.rail__btn svg {
  display: block;
  width: 1.125rem;
  height: 1.125rem;
}

.rail__btn:hover {
  background: rgba(255, 255, 255, 0.34);
}

.rail__btn[disabled] {
  opacity: 0;
  pointer-events: none;
}

.hour {
  flex: none;
  width: 5rem;
  padding: 0.65rem 0.25rem;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, 0.10);
  text-align: center;
  scroll-snap-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15rem;
  transition: background var(--dur) var(--ease);
}

.hour:hover {
  background: rgba(255, 255, 255, 0.18);
}

.hour--now {
  background: rgba(255, 255, 255, 0.24);
}

.hour__time {
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--ink-soft);
}

.hour__emoji {
  font-size: 1.5rem;
  line-height: 1.2;
}

.hour__temp {
  font-size: 1.0625rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.hour__pop {
  min-height: 1rem;
  font-size: 0.75rem;
  font-weight: 600;
  color: #9fdcff;
}

.fav {
  flex: none;
  width: 10.5rem;
  padding: 0.9rem;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, 0.10);
  text-align: left;
  cursor: pointer;
  scroll-snap-align: start;
  color: inherit;
  transition: background var(--dur) var(--ease);
}

.fav:hover {
  background: rgba(255, 255, 255, 0.18);
}

.fav__name {
  font-size: 0.9375rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fav__body {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
}

.fav__emoji {
  font-size: 2rem;
  line-height: 1;
}

.fav__temp {
  font-size: 1.75rem;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}

.fav__meta {
  margin-top: 0.1rem;
  font-size: 0.75rem;
  color: var(--ink-faint);
}

/* ============================================================
   14. PRECIPITATION CHART
   ============================================================ */

.precip {
  display: grid;
  grid-template-columns: 2.75rem 1fr;
  gap: var(--sp-2);
  padding: var(--sp-4);
}

.precip__scale {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 8rem;
  font-size: 0.6875rem;
  color: var(--ink-faint);
  text-align: right;
  padding-right: 0.35rem;
}

.precip__plot {
  min-width: 0;
}

.precip__bars {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 8rem;
  padding: 0 0.15rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.20);
  /* Faint 50% guide line so the scale on the left means something. */
  background: linear-gradient(
    to bottom,
    transparent calc(50% - 1px),
    rgba(255, 255, 255, 0.12) calc(50% - 1px),
    rgba(255, 255, 255, 0.12) 50%,
    transparent 50%
  );
}

.precip__bar {
  flex: 1;
  min-width: 0;
  border-radius: 3px 3px 0 0;
  background: rgba(125, 211, 252, 0.45);
  transition: background var(--dur) var(--ease);
}

.precip__bar--mid {
  background: rgba(125, 211, 252, 0.75);
}

.precip__bar--high {
  background: #7dd3fc;
}

.precip__axis {
  display: flex;
  justify-content: space-between;
  margin-top: 0.4rem;
  font-size: 0.6875rem;
  color: var(--ink-faint);
}

/* ============================================================
   15. WEEKLY
   ============================================================ */

/* Columns sized to their longest real content so the gaps match the
   emoji-to-temperature gap, which is the one that looks right.
   day fits "Today" and "Aug 12"; sun fits an emoji plus "10:48 PM". */
.week__row {
  display: grid;
  grid-template-columns: 3.75rem 2.25rem minmax(0, 1fr) 5.5rem;
  align-items: center;
  gap: var(--sp-3);
  padding: 0.9rem var(--sp-5);
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
  font-variant-numeric: tabular-nums;
}

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

.week__day {
  font-size: 1rem;
  font-weight: 600;
  white-space: nowrap;
  min-width: 0;
}

.week__day small {
  display: block;
  font-size: 0.75rem;
  font-weight: 400;
  color: var(--ink-faint);
}

.week__emoji {
  font-size: 1.6rem;
  line-height: 1;
  text-align: center;
}

.week__range {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-width: 0;
}

.week__lo,
.week__hi {
  flex: none;
  width: 2.6rem;
  font-size: 1rem;
  font-weight: 500;
}

.week__lo {
  color: var(--ink-faint);
  text-align: right;
}

.week__bar {
  position: relative;
  flex: 1;
  min-width: 2rem;
  height: 0.375rem;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0.16);
  overflow: hidden;
}

.week__fill {
  position: absolute;
  top: 0;
  bottom: 0;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, #7ddfff, #ffd24a, #ff9447);
}

.week__sun {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  font-size: 0.875rem;
  color: var(--ink-soft);
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* The day column used to be 1fr here, so it absorbed every spare pixel and
   shoved the temperatures to the far right with a canyon in between. The
   flexible column belongs on the temperature range instead. Raised from
   760px because the sun times were being squeezed and clipped in the
   700-860 band. */
@media (max-width: 860px) {
  .week__row {
    grid-template-columns: 3.25rem 1.75rem minmax(0, 1fr);
    gap: var(--sp-2);
    padding: 0.8rem var(--sp-3);
  }
  .week__sun {
    display: none;
  }
  .week__emoji {
    font-size: 1.4rem;
  }
  .week__lo,
  .week__hi {
    width: 2.3rem;
  }
  .week__range {
    gap: var(--sp-2);
  }
}

/* Very small phones: the bar has nothing useful left to show, so drop it
   and let the temperatures sit next to the day. */
@media (max-width: 340px) {
  .week__bar {
    display: none;
  }
  .week__range {
    justify-content: flex-end;
  }
}

/* ============================================================
   16. MAP
   ============================================================ */

.map {
  overflow: hidden;
}

.map__frame {
  display: block;
  width: 100%;
  height: 26rem;
  border: 0;
}

/* ============================================================
   17. MODAL
   ============================================================ */

.modal {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: grid;
  place-items: center;
  padding: var(--sp-4);
  background: rgba(4, 9, 26, 0.66);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

.modal[hidden] {
  display: none;
}

.modal__panel {
  width: 100%;
  max-width: 26rem;
  max-height: 86svh;
  overflow-y: auto;
  padding: var(--sp-5);
  border-radius: var(--r-lg);
  background: rgba(16, 24, 54, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.24);
  box-shadow: var(--shadow-lg);
  animation: rise var(--dur) var(--ease);
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(10px) scale(0.985);
  }
}

.modal__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-3);
}

.modal__title {
  font-size: 1.25rem;
  font-weight: 600;
}

.modal__desc {
  margin: var(--sp-2) 0 var(--sp-4);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ink-soft);
}

.modal__close {
  flex: none;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.12);
}

.modal__close:hover {
  background: rgba(255, 255, 255, 0.22);
}

.field {
  display: block;
  margin-bottom: var(--sp-3);
}

.field__label {
  display: block;
  margin-bottom: var(--sp-1);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--ink-soft);
}

.field__input {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, 0.10);
  border: 1px solid var(--glass-border);
  outline: none;
}

.field__input:focus {
  border-color: rgba(255, 255, 255, 0.5);
}

.check {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-3);
  margin-bottom: var(--sp-2);
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, 0.07);
  cursor: pointer;
}

.check:hover {
  background: rgba(255, 255, 255, 0.12);
}

/* Explicitly native, and big enough to hit with a thumb. accent-color tints
   the checked state to match the app instead of the browser's default blue. */
.check input[type="checkbox"] {
  -webkit-appearance: checkbox;
  appearance: checkbox;
  flex: none;
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.15rem;
  accent-color: #7dd3fc;
  cursor: pointer;
}

/* The severity dropdown sits on a dark panel, so it needs its own colours
   and its own arrow. Browsers render native selects with system colours
   that can come out white on white here. */
.field__input,
select.field__input {
  -webkit-appearance: none;
  appearance: none;
  color: var(--ink);
}

select.field__input {
  padding-right: 2.25rem;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.85rem center;
}

/* The dropdown list itself is drawn by the operating system, so it needs a
   readable colour pair of its own. */
select.field__input option {
  background: #16234d;
  color: #ffffff;
}

.check__title {
  font-size: 0.9375rem;
  font-weight: 600;
}

.check__desc {
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ink-faint);
}

/* ============================================================
   18. TOASTS
   ============================================================ */

.toasts {
  position: fixed;
  left: 50%;
  bottom: calc(var(--sp-5) + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: 400;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  width: min(26rem, calc(100vw - 2rem));
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-md);
  background: rgba(16, 24, 54, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.24);
  box-shadow: var(--shadow-lg);
  font-size: 0.9375rem;
  pointer-events: auto;
  animation: rise var(--dur) var(--ease);
}

.toast--error { border-color: rgba(255, 91, 110, 0.6); }
.toast--ok { border-color: rgba(92, 225, 166, 0.6); }

.toast__x {
  margin-left: auto;
  display: grid;
  place-items: center;
  opacity: 0.6;
}

.toast__x:hover {
  opacity: 1;
}

/* ============================================================
   19. LOADING
   ============================================================ */

.loadbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 500;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.12);
}

.loadbar[hidden] {
  display: none;
}

.loadbar::after {
  content: "";
  position: absolute;
  inset: 0;
  width: 40%;
  background: linear-gradient(90deg, transparent, #fff, transparent);
  animation: slide 1.1s ease-in-out infinite;
}

@keyframes slide {
  from { transform: translateX(-100%); }
  to { transform: translateX(320%); }
}

.skeleton {
  border-radius: var(--r-sm);
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0.08) 25%,
    rgba(255, 255, 255, 0.18) 37%,
    rgba(255, 255, 255, 0.08) 63%
  );
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
  color: transparent !important;
}

@keyframes shimmer {
  to { background-position: -135% 0; }
}

.splash {
  position: fixed;
  inset: 0;
  z-index: 900;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(1rem, 4vh, 2.5rem);
  padding: clamp(1rem, 4vw, 2.5rem);
  background: linear-gradient(160deg, #38bdf8, #2563eb 50%, #4338ca);
  transition: opacity 700ms var(--ease);
}

.splash--out {
  opacity: 0;
  pointer-events: none;
}

/* Fill the viewport the way a native app splash does. The box is sized to
   the screen and object-fit: contain scales the artwork to whichever axis
   runs out first, so it never crops and never distorts, in any orientation.
   The source is 2048px square, so even a large desktop renders it below
   native resolution and it stays sharp.
   svh rather than vh so mobile browser chrome does not clip it. */
.splash img {
  width: 100%;
  max-width: 94vw;
  height: 74vh;
  height: 74svh;
  object-fit: contain;
}

/* The credit was baked into the artwork as black text on a dark blue
   gradient, which measured 2.7:1 contrast and failed WCAG at any size.
   As real text it sits at 6.3:1, and the year comes from the clock so it
   cannot go stale the way a date inside a PNG does. */
.splash__credit {
  margin: 0;
  font-size: clamp(0.8125rem, 2.2vw, 1rem);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #dfe6ff;
  text-align: center;
}

@media (orientation: landscape) and (max-height: 600px) {
  .splash {
    gap: 0.75rem;
  }
  .splash img {
    height: 68svh;
  }
}

.boot-error {
  margin-top: var(--sp-5);
  padding: var(--sp-5);
  border-left: 3px solid var(--sev-severe);
  border-radius: var(--r-md);
}

.boot-error h2 {
  margin-bottom: var(--sp-3);
  font-size: 1.25rem;
  font-weight: 600;
}

.boot-error p {
  margin-bottom: var(--sp-2);
  color: var(--ink-soft);
  line-height: 1.65;
  overflow-wrap: anywhere;
}

/* ============================================================
   20. FOOTER AND LEGAL PAGES
   ============================================================ */

.footer {
  margin-top: var(--sp-6);
  padding: var(--sp-5) var(--sp-4) var(--sp-6);
  text-align: center;
  font-size: 0.8125rem;
  color: var(--ink-soft);
  line-height: 1.85;
}

.footer__links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-2) var(--sp-4);
  margin-bottom: var(--sp-3);
}

.footer__links a {
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.3);
}

.footer__links a:hover {
  border-bottom-color: #fff;
}

.footer__legal {
  max-width: 44rem;
  margin: var(--sp-2) auto 0;
  font-size: 0.75rem;
  color: var(--ink-faint);
}

.doc {
  max-width: 46rem;
  margin-inline: auto;
  padding: var(--sp-6) var(--sp-5);
  line-height: 1.75;
}

.doc h1 {
  margin-bottom: var(--sp-2);
  font-size: clamp(1.8rem, 5vw, 2.5rem);
  font-weight: 600;
  letter-spacing: -0.015em;
}

.doc h2 {
  margin-top: var(--sp-6);
  margin-bottom: var(--sp-2);
  font-size: 1.25rem;
  font-weight: 600;
}

.doc p,
.doc li {
  margin-bottom: var(--sp-3);
  color: var(--ink-soft);
}

.doc a {
  color: #fff;
}

.doc__updated {
  margin-top: 0;
  font-size: 0.8125rem;
  color: var(--ink-faint);
}

.doc__callout {
  margin: var(--sp-5) 0;
  padding: var(--sp-4) var(--sp-5);
  border-left: 3px solid var(--sev-severe);
  background: rgba(255, 148, 71, 0.12);
}

.doc__callout p {
  margin: 0;
  color: var(--ink);
}

.doc__back {
  margin-top: var(--sp-6);
}

.noscript-card {
  padding: var(--sp-5);
}

/* ============================================================
   21. PREFERENCES AND FALLBACKS
   ============================================================ */

/* Small phones. The search row has two buttons competing with the input,
   so tighten the gaps rather than letting the field shrink to nothing. */
@media (max-width: 430px) {
  .search__bar {
    gap: 0.35rem;
    padding: 0.4rem;
  }
  .search__icon {
    margin-left: 0.25rem;
  }
  .search__bar .btn {
    padding: 0 0.65rem;
  }
  .toolbar {
    gap: 0.4rem;
  }
  .btn {
    padding: 0 0.75rem;
  }
  .now {
    --card-pad: 1.15rem;
  }
  .week__row {
    padding-inline: var(--sp-3);
  }
  .precip {
    grid-template-columns: 2.25rem 1fr;
  }
}

/* Short landscape phones. Trim the tallest fixed heights so the forecast
   is not pushed entirely below the fold. */
@media (max-height: 520px) and (orientation: landscape) {
  .masthead__logo {
    height: 4.5rem;
  }
  .map__frame {
    height: 18rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

@supports not (backdrop-filter: blur(1px)) {
  .glass,
  .btn,
  .rail__btn {
    background: rgba(11, 26, 63, 0.74);
  }
}

@media print {
  .sky,
  .grain,
  .toolbar,
  .jumpnav,
  .search,
  .map,
  .rail__btn {
    display: none !important;
  }
  body {
    background: #fff;
    color: #000;
  }
}
