/* Neenah, WI Weather — dark-first, condition-themed, no framework. */

:root {
  --bg:      #11161d;
  --panel:   #19202a;
  --panel-2: #212b37;
  --ink:     #e8eef6;
  --muted:   #97a6b8;
  --line:    #2c3846;
  --accent:  #5b9bd5;
  --hi:      #f2b34b;
  --lo:      #7fb3e0;
  --warn:    #c8452f;
  --radius:  14px;
  --scene-a: #1b2942;
  --scene-b: #11161d;
  color-scheme: dark;
}

/* Condition theming. One attribute drives the accent and the backdrop. */
html[data-condition="clear"]     { --accent:#6fb1e8; --scene-a:#1d3a63; --scene-b:#11161d; }
html[data-condition="partly"]    { --accent:#5b9bd5; --scene-a:#1f3350; --scene-b:#11161d; }
html[data-condition="overcast"]  { --accent:#8592a3; --scene-a:#232c38; --scene-b:#11161d; }
html[data-condition="fog"]       { --accent:#9fb0bd; --scene-a:#2a3440; --scene-b:#141a22; }
html[data-condition="rain"]      { --accent:#5f8fb5; --scene-a:#1b2b39; --scene-b:#10151c; }
html[data-condition="storm"]     { --accent:#8a6fc4; --scene-a:#2a2340; --scene-b:#10131c; }
html[data-condition="severe"]    { --accent:#d4553c; --scene-a:#3a1c18; --scene-b:#14100f; }
html[data-condition="frigid"]    { --accent:#79b6de; --scene-a:#16304a; --scene-b:#0e1319; }
html[data-condition="scorching"] { --accent:#e2893c; --scene-a:#43281a; --scene-b:#15100c; }
html[data-condition="wind"]      { --accent:#79a9a0; --scene-a:#1d3330; --scene-b:#10161a; }
html[data-condition="smoke"]     { --accent:#c08a52; --scene-a:#3a2c1e; --scene-b:#15110d; }
html[data-condition="snow"]      { --accent:#a8c6e0; --scene-a:#26364a; --scene-b:#121820; }
html[data-condition="ice"]       { --accent:#8fd0d8; --scene-a:#1f3a42; --scene-b:#101619; }

/* After dark the artwork is already dim, so let more of it through. */
html[data-daynight="night"] #scene-photo.ready { opacity: .8; }

* { box-sizing: border-box; }

body {
  margin: 0;
  padding: 0 16px 48px;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  max-width: 900px;
  margin-inline: auto;
}

/* Backdrop. The gradient always renders; a photo layers over it when one
   exists for the condition. Missing images simply fall back to the gradient,
   so shipping artwork one condition at a time is safe. */
#scene {
  position: fixed;
  inset: 0 0 auto 0;
  height: 46vh;
  z-index: -1;
  background: linear-gradient(170deg, var(--scene-a) 0%, var(--scene-b) 78%);
  transition: background 600ms ease;
}
/* The photo layer. app.js sets background-image on this element directly:
   a url() inside a custom property resolves against the stylesheet, not the
   document, which silently 404s every path. Setting it here also means only
   the crop actually in use gets downloaded. */
#scene-photo {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center 38%;
  /* Fade into the page so text stays readable over any photo. */
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 55%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 0%, #000 55%, transparent 100%);
  opacity: 0;
  transition: opacity 500ms ease;
}
#scene-photo.ready { opacity: .58; }

/* --- How much lighthouse you see ------------------------------------------
   Two different problems. On desktop the cards are narrow and sit left, so
   the tower shows beside them. On phones there is no room beside anything,
   so the content starts lower and the photo gets the space above it. */

@media (min-width: 769px) {
  /* Left-align the whole column instead of centring it. Centred, the card's
     right edge lands past the middle of the window, which is exactly where
     the tower is, so it was always covered. */
  body { margin-inline: 0 auto; padding-left: max(24px, 3vw); }

  /* Full height so `cover` scales the art by height and overflows
     horizontally. Without that overflow background-position-x is inert. */
  #scene { height: 100vh; }

  /* Only the two summary cards narrow; the 7-day grid and hourly table
     still use the full width. */
  #app > .card { max-width: min(400px, 40vw); margin-right: auto; }

  /* Lower percentages reveal more of the frame's left side, which pushes the
     centred subject further right, away from the cards. */
  #scene-photo { background-position: 25% 30%; }
}

@media (max-width: 768px) {
  #scene { height: 62vh; }
  /* Start the content below the tower. vh keeps it proportional across
     phone sizes; the cap stops it stranding content on a short landscape
     screen. */
  #app { padding-top: min(26vh, 230px); }
  /* An alert outranks the view. Drop the offset so it lands on the first
     screen; app.js sets data-alerts when there is one. */
  html[data-alerts="yes"] #app { padding-top: 8px; }
  #scene-photo { background-position: center 30%; }
}

a { color: var(--accent); }

/* The header sits directly on the photo, which can be bright sky or dark
   storm, so it carries its own shadow rather than relying on the artwork. */
.topbar {
  display: flex; align-items: baseline; gap: 14px;
  flex-wrap: wrap;
  padding: 20px 0 8px;
  text-shadow: 0 1px 3px rgba(0,0,0,.55), 0 2px 18px rgba(0,0,0,.75);
}
.back { text-decoration: none; font-size: .9rem; color: #fff; opacity: .9; }
.back:hover { opacity: 1; }
h1 { font-size: 1.4rem; margin: 0; letter-spacing: -.01em; color: #fff; }

/* Install button — sits at the far right of the header, quiet until hovered.
   app.js unhides it only when the browser actually offers installation. */
.install {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 12px;
  font-size: .85rem; line-height: 1;
  color: #fff;
  background: color-mix(in srgb, var(--panel) 55%, transparent);
  border: 1px solid color-mix(in srgb, #fff 24%, transparent);
  border-radius: 999px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  cursor: pointer;
  text-shadow: none;
  transition: background 160ms ease, border-color 160ms ease;
}
.install:hover { background: color-mix(in srgb, var(--accent) 34%, transparent);
                 border-color: color-mix(in srgb, #fff 45%, transparent); }
.install svg { width: 17px; height: 17px; display: block; }

/* Tight screens keep the icon and drop the word. */
@media (max-width: 420px) {
  .install-label { display: none; }
  .install { padding: 8px; }
}

/* iOS has no install event, so it gets instructions instead. */
.install-help {
  position: fixed; inset: auto 16px 16px; z-index: 20;
  max-width: 420px; margin-inline: auto;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px;
  box-shadow: 0 18px 50px rgba(0,0,0,.5);
}
.install-help p { margin: 0 0 10px; font-size: .95rem; }
.install-help strong { font-size: 1rem; }
h2 { font-size: 1rem; margin: 0 0 10px; color: var(--muted); font-weight: 600;
     text-transform: uppercase; letter-spacing: .06em; }

.state { padding: 28px 0; color: var(--muted); }
.muted { color: var(--muted); font-size: .88rem; }

button {
  font: inherit; color: var(--ink);
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 10px; padding: 10px 16px; cursor: pointer;
}
button:hover { border-color: var(--accent); }

/* Deliberately translucent so the artwork reads through. The blur keeps text
   legible over a busy photo, and the inner highlight stops the card from
   dissolving into a bright sky. */
.card {
  background: color-mix(in srgb, var(--panel) 62%, transparent);
  border: 1px solid color-mix(in srgb, var(--line) 70%, transparent);
  border-radius: var(--radius);
  padding: 18px;
  margin: 0 0 18px;
  backdrop-filter: blur(16px) saturate(120%);
  -webkit-backdrop-filter: blur(16px) saturate(120%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06), 0 8px 28px rgba(0,0,0,.28);
}

/* Browsers without backdrop-filter get a more opaque card instead of
   unreadable text over the photo. */
@supports not (backdrop-filter: blur(1px)) {
  .card { background: color-mix(in srgb, var(--panel) 92%, transparent); }
}

.stale {
  background: #3a3117; border: 1px solid #5d4d1f; color: #f0dca6;
  padding: 10px 14px; border-radius: 10px; font-size: .9rem;
}

/* Alerts */
#alerts { margin-bottom: 18px; display: grid; gap: 10px; }
.alert {
  background: #35150f; border: 1px solid var(--warn); border-left-width: 5px;
  border-radius: 10px; padding: 12px 14px;
  display: grid; gap: 4px;
}
.alert strong { color: #ffb4a0; font-size: 1.02rem; }
.alert span { color: #f0cfc7; font-size: .9rem; }

/* Right now */
.now-main { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.now-temp { font-size: 3.4rem; line-height: 1; font-weight: 300; letter-spacing: -.03em; }
.now-text { font-size: 1.05rem; }

.stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(104px, 1fr));
  gap: 14px 18px; margin: 18px 0 0;
}
.stat dt { color: var(--muted); font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; }
.stat dd { margin: 2px 0 0; font-size: 1.05rem; }

/* Today */
/* Let the temperatures drop to their own line rather than breaking the date. */
.today-head { display: flex; justify-content: space-between; align-items: baseline;
              gap: 4px 12px; flex-wrap: wrap; }
.today-head h2 { text-transform: none; letter-spacing: 0; font-size: 1.1rem;
                 color: var(--ink); white-space: nowrap; }
#today-highlow { font-size: 1.3rem; white-space: nowrap; }
.hi { color: var(--hi); }
.lo { color: var(--lo); }
.sep { color: var(--muted); }
.sentence { margin: 10px 0 0; font-size: 1.06rem; }

/* 7-day */
.days { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(215px, 1fr)); }
.day {
  background: color-mix(in srgb, var(--panel) 80%, transparent);
  border: 1px solid color-mix(in srgb, var(--line) 75%, transparent);
  border-radius: 12px; padding: 14px;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.day h3 { margin: 0 0 6px; font-size: .92rem; color: var(--muted); }
.day-temp { font-size: 1.7rem; font-weight: 400; }
.day-short { margin: 4px 0 0; font-size: .92rem; }
.day-pop { margin: 6px 0 0; font-size: .84rem; color: var(--lo); }
.day details { margin-top: 8px; }
.day summary { cursor: pointer; font-size: .82rem; color: var(--muted); }
.day details p { font-size: .88rem; color: var(--muted); margin: 8px 0 0; }

/* Hourly */
#hourly-toggle { margin: 6px 0 14px; }
.table-scroll { overflow-x: auto; max-height: 70vh; overflow-y: auto;
                border: 1px solid var(--line); border-radius: 12px; }
table.hourly { border-collapse: collapse; width: 100%; font-size: .9rem; }
.hourly th, .hourly td { padding: 7px 10px; text-align: left; white-space: nowrap; }
.hourly thead th {
  position: sticky; top: 0; background: var(--panel-2);
  border-bottom: 1px solid var(--line); font-size: .74rem;
  text-transform: uppercase; letter-spacing: .05em; color: var(--muted); z-index: 1;
}
.hourly tbody tr { border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent); }
.hourly tbody tr.night { background: color-mix(in srgb, #000 22%, transparent); color: var(--muted); }
.hourly td.short { white-space: normal; min-width: 150px; }
tr.daybreak td {
  background: var(--panel-2); font-weight: 600; font-size: .82rem;
  text-transform: uppercase; letter-spacing: .05em; color: var(--accent);
  position: sticky; top: 30px;
}

footer { margin-top: 32px; display: grid; gap: 10px; }

@media (max-width: 480px) {
  .now-temp { font-size: 2.8rem; }
  h1 { font-size: 1.2rem; }
}

@media (prefers-reduced-motion: reduce) {
  #scene { transition: none; }
}

/* The site is dark-first, but respect an explicit light preference. */
@media (prefers-color-scheme: light) {
  :root:not([data-force-dark]) {
    --bg:#f4f7fb; --panel:#ffffff; --panel-2:#eef2f7;
    --ink:#16202c; --muted:#5b6b7d; --line:#d5dee8;
    /* The pale amber and blue were picked for the dark cards and were too weak on white (Swatter #248). */
    --hi:#a85f00; --lo:#1f6fb5;
    color-scheme: light;
  }
  #scene { opacity: .22; }
  /* In light the header sits on the washed-out photo, where white text and a white icon nearly vanished (Swatter #248). */
  :root:not([data-force-dark]) .topbar { text-shadow: none; }
  :root:not([data-force-dark]) .back,
  :root:not([data-force-dark]) h1 { color: var(--ink); }
  :root:not([data-force-dark]) .install { color: var(--ink); border-color: var(--line);
    background: color-mix(in srgb, var(--panel) 80%, transparent); }
}
