/* ==========================================================================
   Shoreline — tokens
   Every colour that sits behind text is opaque and measured, not eyeballed:
   gradients only ever combine stops that keep body text at >=4.5:1.
   ========================================================================== */
:root {
  color-scheme: light;

  --bg: #eaeff7;
  --bg-2: #dce4f1;
  --surface: #f8fafd;
  --surface-2: #e6ecf6;
  --surface-3: #d6e0ef;
  --border: #c8d3e4;
  --border-strong: #a8b6ce;

  --text: #121828;
  --text-muted: #45536b;
  --text-soft: #52617a;

  --accent: #1f5fd6;
  --accent-strong: #1749ab;
  --accent-contrast: #ffffff;
  --ring: #1f5fd6;

  /* data marks (painted in SVG): light enough that page text still reads against them */
  --bar-fill: #b07a3c;
  --bar-track: #c9d5e7;
  --range-fill: #b07a3c;

  /* hero */
  --hero-text: #0e1728;
  --hero-muted: #17283f;
  --hero-chip-bg: rgba(255, 255, 255, 0.44);
  --hero-chip-text: #16233a;

  --hero-clear-day-1: #bfe4ff;
  --hero-clear-day-2: #9ed4ff;
  --hero-clear-day-3: #ffe3ad;
  --hero-clear-night-1: #0b1533;
  --hero-clear-night-2: #16233a;
  --hero-clear-night-3: #24354f;

  --hero-cloudy-day-1: #dbe7f5;
  --hero-cloudy-day-2: #cfd8e6;
  --hero-cloudy-day-3: #b9cfe8;
  --hero-cloudy-night-1: #1a2137;
  --hero-cloudy-night-2: #232c44;
  --hero-cloudy-night-3: #2d3f5c;

  --hero-rain-day-1: #cfe0f2;
  --hero-rain-day-2: #a9bedb;
  --hero-rain-day-3: #93a9c4;
  --hero-rain-night-1: #101c2f;
  --hero-rain-night-2: #1b2a44;
  --hero-rain-night-3: #2b4058;

  --hero-snow-day-1: #eef6ff;
  --hero-snow-day-2: #d6e9fb;
  --hero-snow-day-3: #b3cfe8;
  --hero-snow-night-1: #12202f;
  --hero-snow-night-2: #1d3145;
  --hero-snow-night-3: #2a4459;

  --hero-fog-day-1: #e9eef5;
  --hero-fog-day-2: #cfd8e3;
  --hero-fog-day-3: #adbccb;
  --hero-fog-night-1: #171d28;
  --hero-fog-night-2: #222c39;
  --hero-fog-night-3: #31404f;

  --hero-thunder-day-1: #e4e0ff;
  --hero-thunder-day-2: #c3b8e8;
  --hero-thunder-day-3: #a8a0d6;
  --hero-thunder-night-1: #191333;
  --hero-thunder-night-2: #241d43;
  --hero-thunder-night-3: #33255c;

  /* night skies flip the hero text */
  --hero-text-night: #f0f5ff;
  --hero-muted-night: #c3d3ec;
  --hero-chip-bg-night: rgba(255, 255, 255, 0.14);
  --hero-chip-text-night: #eaf1ff;

  /* Night hours in the hourly strip are a quiet cue, not a selection: in the
     light theme that is a cool tint on the same ink, so the card that stands
     out is the current hour, not everything after 19:00. */
  --night-card: #e3eaf6;
  --night-card-hover: #d9e2f2;
  --night-card-border: #c4d0e5;
  --night-card-text: #121828;
  --night-card-muted: #45536b;

  /* Sun / moon / bolt for the inline SVG weather icons. Decorative: SVG paint is
     never sampled for text contrast, so these chase recognition, not ratios —
     a sun has to read as sunshine on every surface it lands on. */
  --icon-accent: #b06a10;
  --sun-core: #f9b01c;
  --sun-ray: #dd8c05;
  --sun-rim: #a86208;
  --sun-glow: rgba(249, 184, 28, 0.3);
  --moon-fill: #8fa6c6;
  --bolt-fill: #f2a413;

  /* same marks, sitting on the hero sky */
  --icon-accent-hero-day: #ffb32e;
  --sun-core-hero-day: #ffd23f;
  --sun-ray-hero-day: #ffb02e;
  --sun-rim-hero-day: #cf7d00;
  --sun-glow-hero-day: rgba(255, 214, 84, 0.45);
  --icon-accent-hero-night: #ffd98a;
  --moon-fill-hero-night: #e3edff;
  --bolt-fill-hero: #ffc93c;

  /* Temperature gets one colour language, cold -> hot, deep enough to sit on a
     card and on its hover surface without washing out. Cool stays blue on both
     themes: a 14°C day must not read as earth or autumn. */
  /* The week's temperature scale runs cool -> warm in hue, so a mild day (the
     crossover) is a cool-neutral teal and never the olive/brown it used to be:
     "cool" had to look cool. All five clear 4.5:1 on a card in both themes. */
  --temp-cold: #24599e;
  --temp-cool: #14639b;
  --temp-mild: #1b7271;
  --temp-warm: #9c4413;
  --temp-hot: #932a2a;
  --rail-track: #ccd6e6;

  /* Water section. Every panel is opaque and carries its own ink, so contrast is
     measured per panel rather than assumed from the page tokens. */
  --water-panel: #f4f8fc;
  --water-panel-2: #eaf1f8;
  --water-border: #c2d5e5;
  --water-ink: #0f2237;
  --water-muted: #44586f;
  --water-accent: #0c6b80;
  --water-glow: #dfeaf4;

  --rating-good-bg: #e2f1e7;
  --rating-good-border: #a5cbba;
  --rating-good-ink: #0f6b3f;
  --rating-good-soft: #2b5741;

  /* "Fair" is deliberately the same blue-grey as the rest of the app: a warning
     colour there would shout about an ordinary day. */
  --rating-fair-bg: #eaf0f7;
  --rating-fair-border: #c0cfdf;
  --rating-fair-ink: #2b4670;
  --rating-fair-soft: #405066;

  --rating-poor-bg: #f6e9e7;
  --rating-poor-border: #d3b0aa;
  --rating-poor-ink: #8a2a24;
  --rating-poor-soft: #5d322e;

  --tide-line: #0c6b80;
  --tide-area: #d3e6ef;
  --tide-grid: #dde8f2;
  --tide-band: rgba(20, 90, 120, 0.1);
  --tide-now: #9c4808;
  --tide-now-on: #fdf3e7;
  --tide-label: #33465c;
  --tide-kind: #6b7d92;

  --moon-void: rgba(30, 60, 90, 0.14);
  --moon-lit: #b8791b;
  --moon-edge: rgba(30, 60, 90, 0.4);
  --water-eye: #ffffff;
  --moon-crater: rgba(60, 78, 104, 0.22);

  --shadow-1: 0 1px 2px rgba(14, 23, 40, 0.07), 0 8px 20px -12px rgba(14, 23, 40, 0.22);
  --shadow-2: 0 2px 6px rgba(14, 23, 40, 0.1), 0 18px 38px -18px rgba(14, 23, 40, 0.32);
  --radius: 20px;
  --radius-sm: 14px;
  --radius-pill: 999px;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur: 190ms;
}

html[data-theme="dark"] {
  color-scheme: dark;

  --bg: #0c1322;
  --bg-2: #05080f;
  --surface: #151f31;
  --surface-2: #1b2740;
  --surface-3: #223050;
  --border: #2b3a56;
  --border-strong: #3d5070;

  --text: #e9eefb;
  --text-muted: #9fb0c9;
  --text-soft: #b7c6dd;

  --accent: #6ea2ff;
  --accent-strong: #9fc0ff;
  --accent-contrast: #06101f;
  --ring: #6ea2ff;

  --bar-fill: #8a6034;
  --bar-track: #26344e;
  --range-fill: #8a6034;

  --hero-chip-bg: rgba(255, 255, 255, 0.44);
  --icon-accent: #ffc65c;
  --sun-core: #ffc23a;
  --sun-ray: #ffb42e;
  --sun-rim: #d98a12;
  --sun-glow: rgba(255, 196, 58, 0.26);
  --moon-fill: #cfdcf5;
  --bolt-fill: #ffc23a;

  --icon-accent-hero-day: #ffce55;
  --sun-core-hero-day: #ffdf6b;
  --sun-ray-hero-day: #ffc53d;
  --sun-rim-hero-day: #e09a1e;
  --sun-glow-hero-day: rgba(255, 214, 84, 0.34);
  --icon-accent-hero-night: #ffd98a;
  --moon-fill-hero-night: #eaf2ff;
  --bolt-fill-hero: #ffd45c;

  /* daytime skies are re-tokened below (html[data-theme=dark] .hero…) */
  --temp-cold: #7fb2ff;
  --temp-cool: #6fc6e8;
  --temp-mild: #79cdbf;
  --temp-warm: #ffb27a;
  --temp-hot: #ff9ea3;
  --rail-track: #33415c;

  /* the water panels lift a step off the page, with their own ink */
  --water-panel: #16233a;
  --water-panel-2: #1d2c46;
  --water-border: #32456a;
  --water-ink: #e9f1fb;
  --water-muted: #b3c6de;
  --water-accent: #63d0e4;
  --water-glow: #1b2b45;

  --rating-good-bg: #10301f;
  --rating-good-border: #2f6b4c;
  --rating-good-ink: #85e0a8;
  --rating-good-soft: #c2e6d2;

  --rating-fair-bg: #1c2a44;
  --rating-fair-border: #3c517a;
  --rating-fair-ink: #a9c8ff;
  --rating-fair-soft: #cfdcf0;

  --rating-poor-bg: #35191b;
  --rating-poor-border: #7c4448;
  --rating-poor-ink: #ff9d99;
  --rating-poor-soft: #f0c8c6;

  --tide-line: #58c4da;
  --tide-area: #1e3a55;
  --tide-grid: #24395a;
  --tide-band: rgba(150, 200, 235, 0.13);
  --tide-now: #ffb265;
  --tide-now-on: #2a1503;
  --tide-label: #cdddf1;
  --tide-kind: #9db2cc;

  --moon-void: rgba(190, 210, 235, 0.16);
  --moon-lit: #ffd98a;
  --moon-edge: rgba(200, 218, 240, 0.5);
  --water-eye: #10233c;
  --moon-crater: rgba(20, 32, 52, 0.35);

  /* in the dark theme the night cue is a subtle depth step, one small lift
     below the card surface - not a hole punched in the page */
  --night-card: #0d1524;
  --night-card-hover: #131d30;
  --night-card-border: #223050;
  --night-card-text: #eaf1ff;
  --night-card-muted: #b3c2dc;

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.5), 0 10px 24px -14px rgba(0, 0, 0, 0.7);
  --shadow-2: 0 2px 8px rgba(0, 0, 0, 0.55), 0 22px 44px -20px rgba(0, 0, 0, 0.8);
}

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

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

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background-color: var(--bg);
  background-image: linear-gradient(178deg, var(--bg) 0%, var(--bg-2) 100%);
  color: var(--text);
  font-family: ui-rounded, "SF Pro Rounded", -apple-system, BlinkMacSystemFont, "Segoe UI",
    Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  font-size: 16px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
}

[hidden] {
  display: none !important;
}

h1, h2, h3, p, figure, ul, ol {
  margin: 0;
}
ul, ol {
  padding: 0;
  list-style: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  min-width: 44px;
  min-height: 44px;
}

input {
  font: inherit;
}

svg {
  display: block;
  flex: none;
}

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

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
  /* theme cross-fade: the page and every painted surface ease between the two
     token sets instead of snapping */
  html, body, .shell {
    transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
  }
  .card, .hero, .chip, .btn, .search__input, .icon-btn, .hour, .day,
  .match-option, .unit-toggle, .clear-recents, .metric, .panel, .hint-pill,
  .empty-state, .empty-hint, .section__icon, .brand__mark, .day-date,
  .hour-label, .day-condition, .footnote, .sk {
    transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease),
      color var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
      transform var(--dur) var(--ease);
  }
  .hero.is-entering, .card.is-entering, .strip-wrap.is-entering {
    animation: rise 420ms var(--ease) both;
  }
  .sk::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background-image: linear-gradient(90deg, #ffffff00, #ffffff47, #ffffff00);
    animation: shimmer 1.6s infinite;
  }
  html[data-theme="dark"] .sk::after {
    background-image: linear-gradient(90deg, #ffffff00, #ffffff17, #ffffff00);
  }
}

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

/* Transform only: text must never sit at partial opacity, or anything sampling
   contrast mid-reveal reads washed-out text. */
@keyframes rise {
  from { transform: translateY(12px); }
  to { transform: none; }
}

@keyframes shimmer {
  100% { transform: translateX(100%); }
}

/* ==========================================================================
   Layout
   ========================================================================== */
.shell {
  width: 100%;
  max-width: 44rem;
  margin: 0 auto;
  padding: 0 16px 44px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  flex: 1;
}

.app-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 20px 0 2px;
}

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

.brand__mark {
  width: 40px;
  height: 40px;
  border-radius: 14px;
  display: grid;
  place-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
  color: var(--accent);
}

.brand__name {
  display: block;
  font-size: 1.1875rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
}

.brand__tag {
  display: block;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-muted);
}

.header__actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
}

.icon-btn {
  width: 46px;
  height: 46px;
  border-radius: var(--radius-pill);
  display: grid;
  place-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  box-shadow: var(--shadow-1);
}

.icon-btn:hover {
  background: var(--surface-2);
  border-color: var(--border-strong);
}

.icon-btn:active {
  transform: scale(0.94);
}

.theme-icon--moon {
  display: none;
}
html[data-theme="dark"] .theme-icon--sun {
  display: none;
}
html[data-theme="dark"] .theme-icon--moon {
  display: block;
}

/* ==========================================================================
   Search
   ========================================================================== */
.search {
  display: grid;
  gap: 10px;
}

.search__field {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.search__label {
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding-left: 4px;
}

.search__input {
  width: 100%;
  min-height: 54px;
  padding: 13px 18px;
  border-radius: var(--radius-pill);
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 1.0625rem;
  font-weight: 600;
  box-shadow: var(--shadow-1);
}

.search__input::placeholder {
  color: var(--text-soft);
  opacity: 1;
  font-weight: 500;
}

.search__input:hover {
  border-color: var(--border-strong);
}

.search__input:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
  border-color: transparent;
}

.search__actions {
  display: flex;
  gap: 10px;
  align-items: center;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 54px;
  padding: 13px 24px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--accent-contrast);
  font-weight: 700;
  box-shadow: var(--shadow-2);
  white-space: nowrap;
}

.btn:hover {
  background: var(--accent-strong);
}

.btn:active {
  transform: translateY(1px);
}

.search__submit {
  flex: 1 1 auto;
}

.unit-toggle {
  position: relative;
  flex: 0 0 auto;
  width: 76px;
  min-width: 76px;
  height: 54px;
  border-radius: var(--radius-pill);
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  font-weight: 800;
  font-size: 1rem;
  box-shadow: var(--shadow-1);
  display: grid;
  place-items: center;
}

.unit-toggle:hover {
  border-color: var(--border-strong);
  background: var(--surface-2);
}

.unit-toggle__dial {
  display: inline-flex;
  align-items: center;
  color: var(--accent);
}

/* ==========================================================================
   Sections
   ========================================================================== */
.section {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.section__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 4px;
  min-height: 24px;
}

.section__icon {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 9px;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--accent);
  flex: none;
}

.section__title {
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* ==========================================================================
   Hero
   ========================================================================== */
.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: 24px;
  padding: 22px 20px 20px;
  color: var(--hero-text);
  background-color: var(--hero-solid, #9ed4ff);
  background-image: linear-gradient(158deg,
    var(--hero-1) 0%, var(--hero-2) 52%, var(--hero-3) 100%);
  border: 1px solid rgba(10, 18, 34, 0.12);
  box-shadow: var(--shadow-2);
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.hero[data-scene$="night"] {
  color: var(--hero-text-night);
  border-color: rgba(0, 0, 0, 0.45);
}

/* The dark theme never shows a lit screen, but daytime here must still read as
   daytime: the same skies as the light theme, dimmed to a screen at night with
   the sun still up. Clear days carry a real warmth in the lower sky; cloud, rain
   and snow stay cool; fog and thunder stay neutral. Light ink, because even the
   warm skies are deep enough to need it. */
html[data-theme="dark"] .hero[data-scene$="day"] {
  color: var(--hero-text-night);
  border-color: rgba(0, 0, 0, 0.45);
}
/* The lightness ceiling here is the muted hero ink (#c3d3ec at 6:1 = luminance
   .0620), so no stop may be lighter than ~#404755. Daytime is lifted as far as
   that allows and the night tokens pushed the other way, because a day sky and a
   night sky at the same luminance are only told apart by a small "NIGHT" label. */
html[data-theme="dark"] .hero[data-scene="clear-day"]   { --hero-1: #1d2c48; --hero-2: #2c4364; --hero-3: #57431f; --hero-solid: #2c4364; }
html[data-theme="dark"] .hero[data-scene="cloudy-day"]  { --hero-1: #2c3240; --hero-2: #383f4e; --hero-3: #3d4756; --hero-solid: #383f4e; }
html[data-theme="dark"] .hero[data-scene="rain-day"]    { --hero-1: #1f3250; --hero-2: #2b4455; --hero-3: #2d4760; --hero-solid: #2b4455; }
html[data-theme="dark"] .hero[data-scene="snow-day"]    { --hero-1: #233340; --hero-2: #31444e; --hero-3: #334956; --hero-solid: #31444e; }
html[data-theme="dark"] .hero[data-scene="fog-day"]     { --hero-1: #292c34; --hero-2: #3b3f49; --hero-3: #3f4754; --hero-solid: #3b3f49; }
html[data-theme="dark"] .hero[data-scene="thunder-day"] { --hero-1: #251f42; --hero-2: #39335a; --hero-3: #42406d; --hero-solid: #39335a; }
html[data-theme="dark"] .hero[data-scene$="day"] .hero__eyebrow,
html[data-theme="dark"] .hero[data-scene$="day"] .feels-line {
  color: var(--hero-muted-night);
}
html[data-theme="dark"] .hero[data-scene$="day"] .metric {
  background: var(--hero-chip-bg-night);
  color: var(--hero-chip-text-night);
  border-color: rgba(255, 255, 255, 0.2);
}

.hero[data-scene="clear-day"]     { --hero-1: var(--hero-clear-day-1); --hero-2: var(--hero-clear-day-2); --hero-3: var(--hero-clear-day-3); --hero-solid: var(--hero-clear-day-2); }
.hero[data-scene="clear-night"]   { --hero-1: var(--hero-clear-night-1); --hero-2: var(--hero-clear-night-2); --hero-3: var(--hero-clear-night-3); --hero-solid: var(--hero-clear-night-2); }
.hero[data-scene="cloudy-day"]    { --hero-1: var(--hero-cloudy-day-1); --hero-2: var(--hero-cloudy-day-2); --hero-3: var(--hero-cloudy-day-3); --hero-solid: var(--hero-cloudy-day-2); }
.hero[data-scene="cloudy-night"]  { --hero-1: var(--hero-cloudy-night-1); --hero-2: var(--hero-cloudy-night-2); --hero-3: var(--hero-cloudy-night-3); --hero-solid: var(--hero-cloudy-night-2); }
.hero[data-scene="rain-day"]      { --hero-1: var(--hero-rain-day-1); --hero-2: var(--hero-rain-day-2); --hero-3: var(--hero-rain-day-3); --hero-solid: var(--hero-rain-day-2); }
.hero[data-scene="rain-night"]    { --hero-1: var(--hero-rain-night-1); --hero-2: var(--hero-rain-night-2); --hero-3: var(--hero-rain-night-3); --hero-solid: var(--hero-rain-night-2); }
.hero[data-scene="snow-day"]      { --hero-1: var(--hero-snow-day-1); --hero-2: var(--hero-snow-day-2); --hero-3: var(--hero-snow-day-3); --hero-solid: var(--hero-snow-day-2); }
.hero[data-scene="snow-night"]    { --hero-1: var(--hero-snow-night-1); --hero-2: var(--hero-snow-night-2); --hero-3: var(--hero-snow-night-3); --hero-solid: var(--hero-snow-night-2); }
.hero[data-scene="fog-day"]       { --hero-1: var(--hero-fog-day-1); --hero-2: var(--hero-fog-day-2); --hero-3: var(--hero-fog-day-3); --hero-solid: var(--hero-fog-day-2); }
.hero[data-scene="fog-night"]     { --hero-1: var(--hero-fog-night-1); --hero-2: var(--hero-fog-night-2); --hero-3: var(--hero-fog-night-3); --hero-solid: var(--hero-fog-night-2); }
.hero[data-scene="thunder-day"]   { --hero-1: var(--hero-thunder-day-1); --hero-2: var(--hero-thunder-day-2); --hero-3: var(--hero-thunder-day-3); --hero-solid: var(--hero-thunder-day-2); }
.hero[data-scene="thunder-night"] { --hero-1: var(--hero-thunder-night-1); --hero-2: var(--hero-thunder-night-2); --hero-3: var(--hero-thunder-night-3); --hero-solid: var(--hero-thunder-night-2); }

.hero__top {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.hero__place {
  min-width: 0;
  flex: 1 1 auto;
}

.hero__eyebrow {
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--hero-muted);
}

.hero[data-scene$="night"] .hero__eyebrow,
.hero[data-scene$="night"] .feels-line {
  color: var(--hero-muted-night);
}

.location-name {
  margin-top: 4px;
  font-size: 1.375rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.18;
  overflow-wrap: anywhere;
}

/* The weather mark, nothing else. Every attempt to paint something around it -
   a tile, a hairline, a haze bloom, a fog band, a star - read to a reviewer as a
   smudge or a rendering glitch, so the mark stands alone on the sky.
   audit/hero-marks.js fails if anything is drawn there again. */
.hero__icon {
  flex: none;
  width: 78px;
  height: 78px;
  display: grid;
  place-items: center;
  --icon-accent: var(--icon-accent-hero-day);
  --sun-core: var(--sun-core-hero-day);
  --sun-ray: var(--sun-ray-hero-day);
  --sun-rim: var(--sun-rim-hero-day);
  --sun-glow: var(--sun-glow-hero-day);
  --bolt-fill: var(--bolt-fill-hero);
}

.hero[data-scene$="night"] .hero__icon,
.hero__icon.icon--deep {
  --icon-accent: var(--icon-accent-hero-night);
  --sun-rim: transparent;
  --moon-fill: var(--moon-fill-hero-night);
}

.current-temperature {
  font-size: clamp(4.5rem, 21vw, 6.75rem);
  font-weight: 800;
  line-height: 0.92;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
}

.current-condition {
  margin-top: 8px;
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.015em;
}

.feels-line {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--hero-muted);
}

.feels-line .feels-like {
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.hero__chips {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

/* Coastal phones lead with the verdicts, so the sky becomes a band: the reading and
   the four metrics share one row instead of stacking, and the card stops being a slab.
   The temperature keeps its size — only the arrangement changes. Phone only: past the
   phone breakpoint the coastal hero is wide enough for its own two-column layout. */
@media (max-width: 619.98px) {
  .is-coastal .hero {
    padding: 12px 16px 13px;
    gap: 10px;
  }
  .is-coastal .hero .hero__top {
    align-items: center;
    gap: 10px;
  }
  .is-coastal .hero .hero__icon {
    width: 58px;
    height: 58px;
  }
  .is-coastal .hero .location-name {
    font-size: 1.125rem;
  }
  .is-coastal .hero .hero__reading {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 14px;
  }
  .is-coastal .hero .current-condition {
    margin-top: 4px;
    font-size: 1.0625rem;
  }
  .is-coastal .hero .feels-line {
    margin-top: 6px;
    font-size: 0.875rem;
  }
  /* One column of sideways metrics beside the temperature. Two columns of stacked
     metrics pushed the temperature block down to ~96px, where "Mainly clear" wrapped
     to two lines and the feels-like line wrapped too — a squeezed hero, not a band. */
  .is-coastal .hero__chips {
    grid-template-columns: minmax(0, 1fr);
    flex: 0 0 138px;
    min-width: 0;
    gap: 4px;
  }
  .is-coastal .hero__chips .metric {
    flex-direction: row;
    align-items: baseline;
    justify-content: space-between;
    min-height: 0;
    padding: 3px 8px;
    gap: 4px;
    border-radius: var(--radius-xs);
  }
  .is-coastal .hero__chips .metric__heading {
    gap: 3px;
  }
  .is-coastal .hero__chips .metric__label {
    font-size: 0.5625rem;
    letter-spacing: 0.04em;
  }
  .is-coastal .hero__chips .metric__value {
    font-size: 0.8125rem;
    white-space: nowrap;
  }
  .is-coastal .hero__chips .metric__icon {
    width: 12px;
    height: 12px;
  }
}

/* Coastal phones spend their first screen on the verdicts, so everything above them
   gives a little room back: the brand tag goes, the search takes one row, the kicker
   line (a place the hero just named) is dropped and the disclaimer shares a line.
   Nothing shrinks below its own legibility or tap-target floor. */
@media (max-width: 619.98px) {
  body.is-coastal .brand__tag {
    display: none;
  }
  body.is-coastal .app-header {
    padding-top: 8px;
  }
  /* The label stays visible — the brief asks for it — and the field keeps the whole
     row, because the placeholder is the invitation ("Search a beach, harbour or
     city") and it only reads as a question at full width. The room comes off the
     control heights instead: 46px is still above the 44px tap floor. */
  body.is-coastal .search {
    gap: 8px;
  }
  body.is-coastal .search__input,
  body.is-coastal .search__submit,
  body.is-coastal .unit-toggle {
    min-height: 46px;
    height: 46px;
  }
  body.is-coastal .search__input {
    padding-top: 10px;
    padding-bottom: 10px;
  }
  body.is-coastal .search__actions {
    gap: 8px;
  }
  body.is-coastal .search__submit {
    padding: 10px 18px;
  }
  body.is-coastal .shell {
    gap: 10px;
  }
  /* The brand mark is decoration, not a target, so it can sit one step smaller here. */
  body.is-coastal .brand__mark {
    width: 34px;
    height: 34px;
    border-radius: var(--radius-xs);
  }
  body.is-coastal .water__kicker {
    display: none;
  }
  body.is-coastal .water {
    gap: 8px;
  }
  body.is-coastal .water__disclaimer {
    padding-top: 0;
  }
  /* The two verdict cards and the tide panel give a little padding, never below the
     point where the reason text starts to crowd. */
  body.is-coastal .rating {
    padding: 8px 10px 9px;
  }
  body.is-coastal .water__panel {
    padding: 12px 13px 13px;
  }
  /* Twelve pixels shorter than the default chart, so the worst honest reason (five
     named factors = six lines at 390px) still leaves the chart whole above the fold. */
  body.is-coastal .tide-chart {
    --tide-chart-height: 128px;
  }
}

/* .hero__reading is a plain column on a phone; the desktop rules put the
   reading and the metrics side by side so the wide card has no empty gutter. */
.hero__reading > .temp-block {
  min-width: 0;
}

.metric {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  min-width: 0;
  min-height: 56px;
  padding: 9px 13px;
  border-radius: var(--radius-sm);
  background: var(--hero-chip-bg);
  color: var(--hero-chip-text);
  border: 1px solid rgba(255, 255, 255, 0.4);
  font-weight: 700;
}

/* No alpha dimming anywhere on the hero: the contrast checker composites
   partial alpha into the foreground, which drops small labels under 4.5:1 on
   the darker skies. Hierarchy comes from size and weight only. */
.metric__heading {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.metric__label {
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.metric__value {
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}

.hero[data-scene$="night"] .metric {
  background: var(--hero-chip-bg-night);
  color: var(--hero-chip-text-night);
  border-color: rgba(255, 255, 255, 0.2);
}

.metric__icon {
  width: 17px;
  height: 17px;
}

/* ==========================================================================
   Hourly strip
   ========================================================================== */
.strip {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  /* padded inside the container rather than pulled out with negative margins,
     so the first card lines up with the rest of the layout */
  padding: 4px 0 12px;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

.hour {
  flex: 0 0 auto;
  width: 68px;
  padding: 10px 6px 12px;
  border-radius: var(--radius-sm);
  background: var(--surface);
  border: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  text-align: center;
  scroll-snap-align: start;
  box-shadow: var(--shadow-1);
}

.hour:hover {
  border-color: var(--border-strong);
  background: var(--surface-2);
}

/* Night hours are the quiet cue in the strip: a cool tint, the moon icon, the
   same ink. The card that stands out is the current hour, whatever the sky. */
.hour.hour--night {
  background: var(--night-card);
  border-color: var(--night-card-border);
  color: var(--night-card-text);
}

.hour.hour--night .hour-label,
.hour.hour--night .hour__nowtag,
.hour.hour--night .hour__precip {
  color: var(--night-card-muted);
}

.hour.hour--night .hour-temperature {
  color: var(--night-card-text);
}

.hour.hour--night:hover {
  background: var(--night-card-hover);
  border-color: var(--border-strong);
}

/* "Now" is the loudest card in the strip in both themes: filled surface, a
   top band, and the only accented text in the row. */
.hour--now {
  background: var(--surface-3);
  border-color: var(--accent);
  box-shadow: inset 0 4px 0 var(--ring), var(--shadow-1);
}

.hour.hour--now .hour__nowtag {
  color: var(--accent-strong);
}

html[data-theme="dark"] .hour.hour--now .hour__nowtag {
  color: var(--accent);
}

.hour--now.hour--night {
  background: var(--night-card-hover);
  border-color: var(--accent);
}

.hour__nowtag {
  font-size: 0.625rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  min-height: 12px;
  line-height: 1.2;
}

.hour-label {
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.hour__icon {
  position: relative;
  width: 27px;
  height: 27px;
}

/* A sun on a night hour card must not wear the same ochre it uses on a light
   one, and vice versa: the mark follows the surface, not the theme. */
.hour__icon.icon--deep,
.day__icon.icon--deep {
  --icon-accent: #ffc65c;
  --sun-core: #ffc94a;
  --sun-ray: #ffc94a;
  --sun-rim: transparent;
  --sun-glow: rgba(255, 201, 74, 0.24);
  --moon-fill: #dbe7ff;
  --bolt-fill: #ffc94a;
}

.hour-temperature {
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.hour__precip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  min-height: 13px;
  font-size: 0.6875rem;
  font-weight: 700;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.hour__precip svg {
  width: 10px;
  height: 10px;
}

/* ==========================================================================
   Forecast
   ========================================================================== */
.days {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.day {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
}

.day:hover {
  border-color: var(--border-strong);
  background: var(--surface-2);
}

.day__icon {
  display: grid;
  place-items: center;
  color: var(--text);
}

.day__main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

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

.day-name {
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: -0.01em;
}

.day-date {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--text-muted);
  letter-spacing: 0.01em;
}

.day-condition {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

.day__range {
  width: 100%;
  height: 6px;
}

.rail-cap {
  fill: rgba(255, 255, 255, 0.92);
}

.rail-fill--cold { fill: var(--temp-cold); }
.rail-fill--cool { fill: var(--temp-cool); }
.rail-fill--mild { fill: var(--temp-mild); }
.rail-fill--warm { fill: var(--temp-warm); }
.rail-fill--hot { fill: var(--temp-hot); }

/* the high figure carries the same hue as its rail */
.day-temps--cold .day-high { color: var(--temp-cold); }
.day-temps--cool .day-high { color: var(--temp-cool); }
.day-temps--mild .day-high { color: var(--temp-mild); }
.day-temps--warm .day-high { color: var(--temp-warm); }
.day-temps--hot .day-high { color: var(--temp-hot); }

.day__meta {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
}

.day-precip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  min-width: 40px;
  justify-content: flex-end;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.day-precip svg {
  width: 11px;
  height: 11px;
}

.day-temps {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  font-variant-numeric: tabular-nums;
}

.day-low {
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--text-muted);
}

.day-high {
  font-size: 1.1875rem;
  font-weight: 800;
  letter-spacing: -0.02em;
}

/* ==========================================================================
   Match picker
   ========================================================================== */
.match-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.match-option {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 58px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  text-align: left;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  box-shadow: var(--shadow-1);
}

.match-option:hover {
  background: var(--surface-2);
  border-color: var(--border-strong);
}

.match-option:active {
  transform: scale(0.995);
}

.match-option__pin {
  color: var(--accent);
  display: grid;
  place-items: center;
}

.match-option__label {
  min-width: 0;
  overflow-wrap: anywhere;
}

.match-option__go {
  margin-left: auto;
  color: var(--accent);
  display: grid;
  place-items: center;
}

/* ==========================================================================
   Notice / error
   ========================================================================== */
.panel {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 18px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
}

.panel__icon {
  width: 46px;
  height: 46px;
  border-radius: 15px;
  display: grid;
  place-items: center;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--accent);
  flex: none;
}

.panel__body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.panel__title {
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: -0.015em;
}

.panel__text {
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

.panel .btn {
  align-self: flex-start;
  margin-top: 8px;
}

.panel--error {
  border-color: #b0737a;
  background: #f8e9ea;
  color: #3d1216;
}

.panel--error .panel__icon {
  background: #efd4d6;
  border-color: #c2848a;
  color: #7d1f27;
}

.panel--error .panel__text {
  color: #4a1d22;
}

.panel--error .btn {
  background: #8e2530;
  color: #ffffff;
}

.panel--error .btn:hover {
  background: #751c26;
}

html[data-theme="dark"] .panel--error {
  border-color: #8d4a52;
  background: #2b161a;
  color: #ffe3e5;
}

html[data-theme="dark"] .panel--error .panel__icon {
  background: #3f1e24;
  border-color: #7d3d45;
  color: #ffb9bd;
}

html[data-theme="dark"] .panel--error .panel__text {
  color: #f2c7ca;
}

html[data-theme="dark"] .panel--error .btn {
  background: #ffb9bd;
  color: #3d1216;
}

html[data-theme="dark"] .panel--error .btn:hover {
  background: #ffd2d5;
}

/* ==========================================================================
   Loading skeleton
   ========================================================================== */
.skeleton {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.sk {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  border: 1px solid var(--border);
}

/* Shaped like the real hero / hour cards / day rows so results do not jump
   the page when they replace the skeleton (heights track the measured cards:
   hero 445px, hour card 165px, day row 82px at 390px wide). */
.sk-hero {
  height: 427px;
  border-radius: 24px;
  padding: 24px 22px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  background: var(--surface);
}

.sk-big {
  height: 74px;
  width: 44%;
  border: 0;
  background: var(--surface-2);
}

.sk-metrics {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin-top: auto;
}

.sk-metric {
  height: 56px;
  border: 0;
  background: var(--surface-2);
}

.sk-strip {
  display: flex;
  gap: 8px;
  overflow: hidden;
}

.sk-hour {
  width: 68px;
  height: 135px;
  flex: none;
}

.sk-line {
  height: 24px;
}

.sk-day {
  height: 83px;
}

/* ==========================================================================
   Recent searches
   ========================================================================== */
.recent {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.recent__head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 4px;
  min-height: 46px;
}

.recent__title {
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.clear-recents {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 44px;
  padding: 10px 15px;
  border-radius: var(--radius-pill);
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 0.8125rem;
  font-weight: 700;
}

.clear-recents:hover {
  background: var(--surface-2);
  color: var(--text);
  border-color: var(--border-strong);
}

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

.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 46px;
  max-width: 100%;
  padding: 10px 16px;
  border-radius: var(--radius-pill);
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  box-shadow: var(--shadow-1);
  text-align: left;
  overflow-wrap: anywhere;
  hyphens: auto;
}

.chip:hover {
  background: var(--surface-2);
  border-color: var(--border-strong);
}

.chip:active {
  transform: scale(0.98);
}

.chip__pin {
  width: 15px;
  height: 15px;
  color: var(--accent);
}

.empty-hint {
  padding: 14px 16px;
  border-radius: var(--radius-sm);
  border: 1px dashed var(--border-strong);
  color: var(--text-muted);
  font-size: 0.9375rem;
  font-weight: 600;
}

/* ==========================================================================
   Empty state
   ========================================================================== */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
  padding: 34px 22px 30px;
  border-radius: 24px;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
  --art-sky-1: #d8e9fd;
  --art-sky-2: #eef5ff;
  --art-sun: #f4b53f;
  --art-cloud: #ffffff;
  --art-cloud-2: #dfe7f3;
  --art-rain: #2f63c4;
  --art-wave: #1d6f88;
  --art-wave-2: #59a7bd;
  --art-spark: #74889f;
}

html[data-theme="dark"] .empty-state {
  --art-sky-1: #1c2f52;
  --art-sky-2: #121d33;
  --art-sun: #f2c56e;
  --art-cloud: #8ea5c7;
  --art-cloud-2: #43557a;
  --art-rain: #86adf7;
  --art-wave: #63c7dd;
  --art-wave-2: #3d8ba6;
  --art-spark: #66798f;
}

.empty-state__art {
  width: 138px;
  height: 120px;
}

.empty-state__title {
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -0.03em;
}

.empty-state__text {
  font-size: 1rem;
  font-weight: 500;
  color: var(--text-muted);
  max-width: 32ch;
}

.empty-state__hints {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-top: 4px;
}

.hint-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 10px 16px;
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 0.9375rem;
  font-weight: 700;
}

.hint-pill svg {
  width: 15px;
  height: 15px;
  color: var(--accent);
}

/* ==========================================================================
   Footer
   ========================================================================== */
.footnote {
  text-align: center;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text-muted);
  padding: 6px 8px 0;
  max-width: 46ch;
  margin: 0 auto;
}

/* ==========================================================================
   The water section — the showpiece for a coastal place
   Every panel here is opaque and carries its own ink; no alpha dimming, no
   gradients under text, so contrast is one measured number per panel.
   ========================================================================== */
.water {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* The kicker names the place again under the hero; on a phone the hero has only
   just said it, so the verdicts get the room instead. */
.water__kicker {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  margin: 0;
  padding: 0 4px;
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.water__kicker svg {
  color: var(--water-accent);
  flex: none;
}

/* The trend reads as a Tide pill, and it rides in the tides header where it is read
   against the curve. "Tide" sits outside the value so the pill says "Tide Rising". */
.tide__head {
  display: flex;
  align-items: center;
  gap: 10px;
}

.tide-trend {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-left: auto;
  padding: 5px 11px 5px 8px;
  border-radius: var(--radius-pill);
  background: var(--water-panel-2);
  border: 1px solid var(--water-border);
  color: var(--water-ink);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
}

.tide-trend svg {
  color: var(--water-accent);
}

.ratings {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.rating {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 10px 11px 11px;
  border-radius: var(--radius-sm);
  background: var(--rating-fair-bg);
  border: 1px solid var(--rating-fair-border);
  border-top-width: 3px;
  border-top-color: var(--rating-fair-ink);
  color: var(--rating-fair-ink);
  box-shadow: var(--shadow-1);
}

.rating--good {
  background: var(--rating-good-bg);
  border-color: var(--rating-good-border);
  border-top-color: var(--rating-good-ink);
  color: var(--rating-good-ink);
}

.rating--poor {
  background: var(--rating-poor-bg);
  border-color: var(--rating-poor-border);
  border-top-color: var(--rating-poor-ink);
  color: var(--rating-poor-ink);
}

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

.rating__mark {
  display: grid;
  place-items: center;
  color: inherit;
  --water-accent: currentColor;
}

.rating__label {
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  min-width: 0;
  overflow-wrap: anywhere;
}

/* The rating never relies on colour alone: a word plus a distinct mark per state. */
.rating__flag {
  margin-left: auto;
  display: grid;
  place-items: center;
  color: inherit;
}

.rating__word {
  margin-top: 2px;
  font-size: 1.625rem;
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.03em;
}

.rating__reason {
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--rating-fair-soft);
  overflow-wrap: anywhere;
}

.rating--good .rating__reason {
  color: var(--rating-good-soft);
}

.rating--poor .rating__reason {
  color: var(--rating-poor-soft);
}

.water__disclaimer {
  margin: 0;
  padding: 0 4px;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-muted);
  max-width: 46ch;
}

.water__panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 14px 15px;
  border-radius: var(--radius);
  background: var(--water-panel);
  border: 1px solid var(--water-border);
  color: var(--water-ink);
  box-shadow: var(--shadow-1);
}

.water__subtitle {
  margin: 0;
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--water-muted);
}

/* ---------------- tide chart ---------------- */
.tide-chart {
  position: relative;
  border-radius: var(--radius-sm);
  background: var(--water-panel-2);
  border: 1px solid var(--water-border);
  overflow: hidden;
  /* the painter reads this box, so the box itself carries the height */
  min-height: var(--tide-chart-height, 136px);
}

/* The SVG is drawn at its box's own pixel size (see Water.paintChart), so it needs no
   scaling here — that is what keeps the stroke even and the labels unstretched. The
   height is opt-in through --tide-chart-height, which the painter reads back. */
.tide-chart__svg {
  display: block;
  width: 100%;
  height: auto;
}

.tide-chart__svg text {
  font-family: inherit;
}

.tc-band {
  fill: var(--tide-band);
}

/* Hour gridlines sit under everything, so they stay the quietest thing in the
   chart — a place-keeper, not a second curve. */
.tc-grid {
  stroke: var(--tide-grid);
  stroke-width: 1;
}

.tc-bandlabel {
  fill: var(--water-muted);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.tc-zero {
  stroke: var(--water-border);
  stroke-width: 1;
  stroke-dasharray: 3 3;
}

.tc-area {
  fill: var(--tide-area);
}

.tc-line {
  fill: none;
  stroke: var(--tide-line);
  stroke-width: 2.4;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.tc-turn circle {
  fill: var(--water-panel-2);
  stroke: var(--tide-line);
  stroke-width: 2;
}

.tc-turn--high circle {
  /* filled disc for a high, hollow ring for a low: the chart carries four turns and
     only the time beside each, so the shape says which is which. The tiles under the
     chart and the legend spell it out in words — the shape is never the only cue. */
  fill: var(--tide-line);
  stroke: var(--tide-line);
}

.tc-turn text {
  fill: var(--tide-label);
  font-size: 10px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.tide-legend {
  display: flex;
  align-items: center;
  gap: 5px;
  margin: 6px 0 0;
  color: var(--water-muted);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.tide-legend__mark {
  width: 7px;
  height: 7px;
  margin-left: 8px;
  border: 2px solid var(--tide-line);
  border-radius: 50%;
}

.tide-legend__mark:first-child {
  margin-left: 0;
}

.tide-legend__mark--high {
  background: var(--tide-line);
}

.tide-legend__now {
  width: 7px;
  height: 7px;
  margin-left: 8px;
  border-radius: 50%;
  background: var(--tide-now);
}

.tc-hour {
  fill: var(--water-muted);
  font-size: 9.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.tc-now line {
  stroke: var(--tide-now);
  stroke-width: 1.6;
  stroke-dasharray: 4 3;
}

.tc-now circle {
  fill: var(--tide-now);
  stroke: var(--water-panel-2);
  stroke-width: 1.6;
}

.tc-nowpill {
  fill: var(--tide-now);
}

.tc-now text {
  /* the word sits on a solid pill of the same colour, so it takes the panel ink */
  fill: var(--tide-now-on);
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

/* ---------------- today's turns ---------------- */
.tide-events {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(78px, 1fr));
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tide-event {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 7px 9px;
  border-radius: var(--radius-xs);
  background: var(--water-panel-2);
  border: 1px solid var(--water-border);
}

.tide-event--none {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--water-muted);
}

.tide-kind {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 0.625rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--water-muted);
}

.tide-kind svg {
  color: var(--water-accent);
}

.tide-time {
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--water-ink);
}

.tide-height {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--water-muted);
  font-variant-numeric: tabular-nums;
}

/* The one line in the tide panel that is always about the future, so it reads first
   and the dawn/dusk commentary reads after it. */
.next-turn {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 8px;
  margin: 8px 0 0;
  font-size: 0.875rem;
  line-height: 1.35;
}

.next-turn__label {
  color: var(--water-muted);
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.next-turn__now {
  color: var(--water-ink);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.next-turn__more {
  color: var(--water-muted);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}

.best-times {
  margin: 0;
  font-size: 0.875rem;
  font-weight: 700;
  line-height: 1.4;
  color: var(--water-ink);
}

/* After sunset the tide panel is the only block still talking about the future, so the
   one line about tomorrow belongs here rather than under the verdicts, which are about
   a day that has finished. Quiet by design: no rating word, no colour of its own. */
.tomorrow {
  margin: -2px 0 0;
  font-size: 0.75rem;
  line-height: 1.4;
}

.tomorrow__label {
  color: var(--water-muted);
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.tomorrow__text {
  color: var(--water-muted);
  font-weight: 600;
}

.tide-note {
  margin: 0;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--water-muted);
}

/* ---------------- sea state ---------------- */
.sea__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.sea__stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 9px 11px;
  border-radius: var(--radius-sm);
  background: var(--water-panel-2);
  border: 1px solid var(--water-border);
}

.sea__label {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 0.625rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--water-muted);
}

.sea__label svg {
  color: var(--water-accent);
  flex: none;
}

.sea__value {
  font-size: 1.25rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--water-ink);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.sea__value--dir {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.sea__value--moon {
  font-size: 1rem;
  line-height: 1.2;
}

/* The arrow points the way the swell travels, i.e. away from the compass point. */
.sea__arrow {
  display: grid;
  place-items: center;
  color: var(--water-accent);
  transform: rotate(calc(var(--dir, 0deg) + 180deg));
}

.sea__sub {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--water-muted);
  overflow-wrap: anywhere;
}

/* Calm note for a failed sea request — deliberately not the error palette. */
.panel--calm {
  margin: 0;
  padding: 14px 18px;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text-muted);
}

/* ==========================================================================
   Bigger screens
   ========================================================================== */
@media (min-width: 620px) {
  .shell {
    max-width: 48rem;
    padding: 0 24px 56px;
    gap: 22px;
  }
  .app-header {
    padding: 30px 0 4px;
  }
  .search {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
  }
  .search__actions {
    align-items: center;
  }
  .search__submit {
    flex: 0 0 auto;
  }
  .hero {
    padding: 28px 30px 24px;
  }
  .sk-hero {
    height: 465px;
  }
  .hero__icon {
    width: 96px;
    height: 96px;
  }
  .current-temperature {
    font-size: clamp(5rem, 12vw, 7rem);
  }
  .location-name {
    font-size: 1.5rem;
  }
  .empty-state {
    padding: 52px 34px 44px;
  }
  .empty-state__art {
    width: 168px;
    height: 146px;
  }
}

@media (min-width: 940px) {
  /* A laptop should see now, the next hours and the week together on first
     load. The hero and the hours share the left column at their natural
     heights, the week spans the right, and nothing stretches to fill. */
  .shell {
    max-width: 72rem;
    display: grid;
    grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
    grid-template-areas:
      "header  header"
      "search  search"
      "hero    week"
      "hours   week"
      "recents recents"
      "foot    foot";
    column-gap: 22px;
    row-gap: 16px;
    align-items: start;
    padding: 0 28px 44px;
  }
  .app-header {
    grid-area: header;
    padding: 18px 0 0;
  }
  .search {
    grid-area: search;
    max-width: 46rem;
  }
  .skeleton, .empty-state, [data-testid="match-list"], [data-testid="notice"],
  [data-testid="error"] {
    grid-area: hero;
  }
  /* A page with one panel has nothing beside it, so that panel owns the whole
     column pair instead of leaving a blank half; the skeleton keeps the hero's
     shape because it is the shape the results will land in. The panel centres
     its own measure so a wide card never becomes a long line of text. */
  .empty-state, [data-testid="match-list"], [data-testid="notice"],
  [data-testid="error"] {
    grid-column: 1 / -1;
  }
  .empty-state__text {
    max-width: 46rem;
  }
  .empty-state__art {
    width: 158px;
    height: 137px;
  }
  .panel, .match-list {
    max-width: 46rem;
    width: 100%;
    margin-inline: auto;
  }
  .panel {
    align-items: center;
    padding: 24px 26px;
  }
  .match-option {
    font-size: 1.0625rem;
    padding: 14px 18px;
  }
  [data-testid="current-weather"] {
    grid-area: hero;
  }
  [data-testid="hourly"] {
    grid-area: hours;
  }
  [data-testid="forecast-days"] {
    grid-area: week;
  }
  .recent {
    grid-area: recents;
  }
  .footnote {
    grid-area: foot;
  }
  .hero {
    padding: 24px 26px 24px;
    gap: 18px;
  }
  .sk-hero {
    height: 335px;
  }
  /* A wide hero puts the metrics beside the reading instead of under it: the
     card's width carries the numbers, so there is no empty gutter next to the
     temperature. */
  .hero__reading {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: end;
    gap: 24px;
  }
  .hero__chips {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .hero__icon {
    width: 96px;
    height: 96px;
  }
  .current-temperature {
    font-size: clamp(5rem, 8.4vw, 6.75rem);
  }
  .location-name {
    font-size: 1.5rem;
  }
  .empty-state {
    padding: 44px 34px 38px;
  }
  .day {
    padding: 14px 16px;
  }
}

/* ==========================================================================
   A coastal place on a wide screen reads as a water dashboard: the verdicts and
   the tide chart beside the current weather. Inland results keep the plain
   two-column layout above.

   The two columns must END together, or a hole opens under whichever one is
   shorter (the operator's review: "a large empty gap between the hero and the
   hourly strip, while the water column runs long beside it"). So the left column
   is the sky column - the poster plus the week, which together measure about what
   the water column does - the hero stretches to soak up any slack (space-between
   turns extra height into air inside the poster rather than a void under it), the
   tide chart grows to fill whatever the water column has left, and the 24-hour
   strip gets a row of its own across the whole width: squeezed into one column it
   showed 7 of 24 hours, which is not a strip, it is a scrollbar.
   ========================================================================== */
@media (min-width: 940px) {
  body.is-coastal .shell {
    grid-template-columns: minmax(0, 1.02fr) minmax(0, 0.98fr);
    grid-template-areas:
      "header  header"
      "search  search"
      "hero    water"
      "week    water"
      "hours   hours"
      "recents recents"
      "foot    foot";
  }
  body.is-coastal [data-testid="water"] {
    grid-area: water;
    /* fill the column, so the last panel sits level with the last card on the left */
    align-self: stretch;
  }
  body.is-coastal #water-body {
    display: flex;
    flex-direction: column;
    gap: 12px;
    flex: 1 1 auto;
    min-height: 0;
  }
  body.is-coastal [data-testid="current-weather"] {
    align-self: stretch;
    /* so the poster card itself fills it: stretching only the section would move the
       void from under the row into the section, which the eye still reads as a hole */
    display: flex;
    flex-direction: column;
  }
  body.is-coastal .hero {
    flex: 1 1 auto;
    /* the extra height becomes air inside the poster, not a gap under it */
    justify-content: space-between;
  }
  body.is-coastal [data-testid="hourly"] {
    grid-area: hours;
  }
  body.is-coastal [data-testid="forecast-days"] {
    grid-area: week;
  }
  /* The week is in the sky column now, one card per row: two-up would stretch
     each card past its measure for nothing. */
  body.is-coastal .days {
    gap: 8px;
  }
  /* Slack in the water column belongs to the chart: more sea level per pixel is
     the one thing in this panel you can always use more of. The panel is the
     only flexible child, so it takes exactly what the week leaves. */
  body.is-coastal .water__panel.tide {
    flex: 1 1 auto;
    min-height: 0;
  }
  body.is-coastal .tide-chart {
    flex: 1 1 auto;
    min-height: var(--tide-chart-height, 176px);
  }
  body.is-coastal .hero .hero__icon {
    width: 84px;
    height: 84px;
  }
  .water {
    gap: 12px;
  }
  /* Verdicts side by side, taller chart, sea state in one row of four: the wide
     column has the room the phone does not. */
  .ratings {
    gap: 12px;
  }
  .rating {
    padding: 14px 16px 15px;
  }
  .rating__word {
    font-size: 1.875rem;
  }
  .tide-chart {
    --tide-chart-height: 176px;
  }
  .water__panel {
    padding: 16px 17px 17px;
  }
  .sea__grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
  .tide-events {
    grid-template-columns: repeat(auto-fit, minmax(72px, 1fr));
  }
}
