/* ============================================================
   wxstation — layout & components (dark navy glass)
   ============================================================ */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; font-family: var(--font); color: var(--txt-1);
  background: var(--bg-0); line-height: 1.45;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  min-height: 100vh;
}
a { color: inherit; text-decoration: none; }
picture { display: contents; }   /* <picture> is a format-picker only -> stay transparent to layout */
h3 { margin: 0; }

/* fixed page background */
.wxs-bg {
  position: fixed; inset: 0; z-index: -2; background: var(--page-grad);
}
.wxs-bg::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(620px 420px at 12% 8%, rgba(79,144,224,.14), transparent 60%),
    radial-gradient(560px 420px at 92% 4%, rgba(123,108,240,.12), transparent 60%);
  filter: blur(8px);
}
/* DESKTOP-only background lights (≥1025px): a brighter blue+purple twin-glow in the top
   corners over a flat base (Lights · Top corners · 80% intensity). MOBILE/TABLET keep the
   original above (--page-grad navy glows + ::after accents). Network-wide 2026-09-17. */
@media (min-width: 1025px) {
  .wxs-bg {
    background:
      radial-gradient(1100px 700px at 14% -6%, rgba(79,144,224,.16), transparent 60%),
      radial-gradient(1000px 680px at 100% 0%, rgba(123,108,240,.136), transparent 60%),
      linear-gradient(168deg, var(--bg-1), var(--bg-0));
  }
  .wxs-bg::after { background: none; }
}
/* ambient reactive star/weather field (JS-built in ui.js, dark theme only):
   fixed, above .wxs-bg (-2) and below content, never intercepts pointer events */
.wxs-starfield { position: fixed; inset: 0; width: 100%; height: 100%; z-index: -1; pointer-events: none; }

/* glass helper — CARDS carry NO backdrop blur. They sit on the smooth page
   gradient, where blurring produces a near-identical result to a plain translucent
   fill, but costs a gaussian pass per card per frame (~18 in view × 120Hz on a
   ProMotion iPhone = heat + battery). The glass read is kept with the translucent
   fill (page gradient tints through), the hairline border, the inset top highlight,
   the drop shadow, and a faint diagonal sheen that fakes the refraction. */
.wxs-card {
  background-color: var(--glass-bg);
  background-image: linear-gradient(150deg, rgba(255,255,255,.05), rgba(255,255,255,0) 46%);
  border: 1px solid var(--glass-brd);
  box-shadow: var(--glass-shadow), var(--inset-hi);
}

/* ============ CARD REVEAL — fade + rise on load / on scroll ============
   Enabled by html.wxs-reveal, added PRE-PAINT by a tiny <head> script and ONLY when motion
   is allowed — so if that script or reveal.js never runs, or the visitor prefers reduced
   motion, every card is simply visible (no JS-gated hidden content). Animates opacity + a
   small translateY only (compositor-only; the cards carry no backdrop-filter so the rise is
   cheap). JS adds .wxs-in to reveal each; html.wxs-reveal-go is a timeout failsafe that
   force-shows everything even if reveal.js fails. */
/* Targets: index → `.wxs-dash .wxs-card` + its 3 sections; every subpage → `.wxs-fcpage__head ~ *`
   (all blocks AFTER the page header, which stays static like index's banner). One shared reveal.js
   drives both. The `.wxs-fcpage__head ~ *` group matches only pages that have a page header (i.e. NOT
   index), so the two groups never collide. */
html.wxs-reveal .wxs-dash .wxs-card,
html.wxs-reveal .wxs-graphs,
html.wxs-reveal .wxs-forecast,
html.wxs-reveal .wxs-media,
html.wxs-reveal .wxs-fcpage__head ~ * {
  opacity: 0; transform: translateY(16px);
  transition: opacity .5s ease, transform .6s cubic-bezier(.22, .61, .36, 1);
}
html.wxs-reveal .wxs-dash .wxs-card.wxs-in,
html.wxs-reveal .wxs-graphs.wxs-in,
html.wxs-reveal .wxs-forecast.wxs-in,
html.wxs-reveal .wxs-media.wxs-in,
html.wxs-reveal .wxs-fcpage__head ~ .wxs-in { opacity: 1; transform: none; }
/* elements revealed ON SCROLL (below the fold at load — tagged .wxs-rv-scroll by reveal.js)
   fade in a touch slower + softer than the snappier on-load stagger. Selectors ordered after the
   bases above so they win for both the card base (.wxs-dash .wxs-card) and the subpage/section bases. */
html.wxs-reveal .wxs-rv-scroll,
html.wxs-reveal .wxs-dash .wxs-rv-scroll {
  transition: opacity .72s ease, transform .82s cubic-bezier(.22, .61, .36, 1);
}
html.wxs-reveal-go .wxs-dash .wxs-card,
html.wxs-reveal-go .wxs-graphs,
html.wxs-reveal-go .wxs-forecast,
html.wxs-reveal-go .wxs-media,
html.wxs-reveal-go .wxs-fcpage__head ~ * { opacity: 1 !important; transform: none !important; transition: none !important; }
@media (prefers-reduced-motion: reduce) {
  html.wxs-reveal .wxs-dash .wxs-card, html.wxs-reveal .wxs-graphs,
  html.wxs-reveal .wxs-forecast, html.wxs-reveal .wxs-media,
  html.wxs-reveal .wxs-fcpage__head ~ * { opacity: 1; transform: none; transition: none; }
}
/* the header floats over the banner PHOTO — real detail behind it, so the blur
   genuinely earns its cost here. `saturate()` dropped: it's a second filter pass. */
.wxs-header__inner {
  background: var(--glass-bg);
  border: 1px solid var(--glass-brd);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  box-shadow: var(--glass-shadow), var(--inset-hi);
}

/* ================= HEADER ================= */
.wxs-header {
  position: sticky; top: 0; z-index: 50; padding: 10px var(--gutter);
}
.wxs-header__inner {
  max-width: var(--maxw); margin: 0 auto; border-radius: var(--r-lg);
  display: flex; align-items: center; gap: 14px;
  padding: 8px 14px; min-height: var(--header-h);
  /* The header bar is a backdrop-filter stacking context; lift it above the subbar below
     so the gear popover can't be pierced by the flashing update-time (its filter animation
     forms its own stacking context that would otherwise paint over the trapped popover). */
  position: relative; z-index: 1;
}
.wxs-brand { display: flex; align-items: center; gap: 11px; flex: none; }
/* the logo and the name are now SEPARATE links: logo -> meteokav.gr homepage, name -> this station's own root */
.wxs-brand__logolink, .wxs-brand__namelink { display: flex; align-items: center; text-decoration: none; color: inherit; border-radius: 8px; }
.wxs-brand__namelink { min-width: 0; transition: opacity .15s ease; }
.wxs-brand__namelink:hover { opacity: .82; }
.wxs-brand__logolink { transition: transform .15s ease, opacity .15s ease; }
.wxs-brand__logolink:hover { opacity: .92; transform: translateY(-1px); }
.wxs-brand__logo { height: 34px; width: auto; display: block; filter: drop-shadow(0 2px 6px rgba(0,0,0,.4)); }
.wxs-brand__txt { padding-left: 11px; border-left: 1px solid var(--glass-brd); }
.wxs-brand__txt strong { display: block; color: var(--txt-0); font-size: 15px; font-weight: 800; letter-spacing: -.2px; }
.wxs-brand__txt small { display: block; color: var(--txt-2); font-size: 11px; margin-top: 1px; }

.wxs-menu { display: flex; align-items: center; gap: 2px; margin: 0 auto; flex-wrap: wrap; }
.wxs-menu a, .wxs-menu-trig {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 600; color: var(--txt-2); font-family: var(--font);
  padding: 7px 11px; border-radius: 9px; white-space: nowrap; transition: color .15s, background .15s;
}
.wxs-mi { width: 16px; height: 16px; flex: none; opacity: .9; }
.wxs-menu a:hover { color: var(--txt-0); background: var(--accent-soft); }
.wxs-menu a.is-active { color: var(--txt-0); background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--glass-brd-hi); }
/* Desktop-only: tint a section's mini-icon in its own accent on HOVER and when it's
   the CURRENT page (Stats too, when a child page is active). Each item carries a
   --sec; the icon is currentColor so it just picks it up. Colours are a first pass —
   retweak freely. Scoped to the horizontal menu (≥1025px); the burger drawer is untouched. */
@media (min-width: 1025px) {
  .wxs-menu [data-sec="mHome"]      { --sec: #6fb1ff; }
  .wxs-menu [data-sec="mForecast"]  { --sec: #6fc0f0; }
  .wxs-menu [data-sec="mSatellite"] { --sec: #4fd0e0; }
  .wxs-menu [data-sec="mLightning"] { --sec: #ffd53d; }
  .wxs-menu [data-sec="mGraphs"]    { --sec: #4fd88f; }
  .wxs-menu [data-sec="mStats"]     { --sec: #a596f5; }
  .wxs-menu [data-sec="mNoaa"]      { --sec: #8ab6ff; }
  .wxs-menu [data-sec="mTables"]    { --sec: #58cfe0; }
  .wxs-menu [data-sec="mHistory"]   { --sec: #ffb454; }
  .wxs-menu [data-sec="mClimate"]   { --sec: #ff9270; }
  .wxs-menu [data-sec="mRecords"]   { --sec: #ffd061; }
  .wxs-menu .wxs-mi { transition: color .16s ease, opacity .16s ease; }
  .wxs-menu [data-sec]:hover .wxs-mi,
  .wxs-menu [data-sec].is-active .wxs-mi,
  .wxs-menu-group.is-active .wxs-menu-trig .wxs-mi { color: var(--sec); opacity: 1; }
}

/* dropdown (Stats) */
.wxs-menu-group { position: relative; }
.wxs-menu-trig {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  background: transparent; border: 0;
}
.wxs-menu-trig:hover { color: var(--txt-0); background: var(--accent-soft); }
.wxs-caret { width: 9px; height: 6px; transition: transform .18s; opacity: .8; }
.wxs-dropdown {
  position: absolute; top: calc(100% + 8px); right: 0; min-width: 190px;
  display: flex; flex-direction: column; gap: 2px; padding: 7px;
  background: rgba(19, 29, 53, 0.97); border: 1px solid var(--glass-brd); border-radius: var(--r-md);
  box-shadow: var(--glass-shadow), var(--inset-hi);
  opacity: 0; visibility: hidden; transform: translateY(-6px); transition: .16s; z-index: 30;
}
.wxs-dropdown a { display: flex; align-items: center; gap: 9px; padding: 8px 11px; }
.wxs-menu-group:hover .wxs-dropdown,
.wxs-menu-group.is-open .wxs-dropdown { opacity: 1; visibility: visible; transform: none; }
.wxs-menu-group:hover .wxs-caret,
.wxs-menu-group.is-open .wxs-caret { transform: rotate(180deg); }

/* header-right: DESKTOP grid — [temp][●LIVE][lang] on the top row, the rotating line
   on its OWN row spanning below temp+LED (width-locked so it can't nudge anything) */
.wxs-head-right { display: grid; align-items: center; column-gap: 9px; row-gap: 1px; flex: none;
  grid-template-columns: auto auto auto auto; grid-template-areas: "temp live theme lang" "rot rot theme lang"; }
.wxs-live { grid-area: live; display: inline-flex; align-items: center; gap: 6px; font-size: 10.5px; font-weight: 700; letter-spacing: .5px; color: var(--good); }
.wxs-live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--good); box-shadow: 0 0 0 0 rgba(70,209,138,.6); animation: wxsPulse 2.4s infinite; }
.wxs-live-dot.offline { background: var(--bad); animation: none; box-shadow: none; }
.wxs-live-dot.flash { animation: wxsFlash .7s; }
/* OFFLINE — no fresh station data for ≥15 min (WXS.state.stale, set in live.js):
   the menu-bar LED word goes red (ΑΝΕΝΕΡΓΟΣ / OFFLINE) and so does the mobile
   last-update mirror that lives inside .wxs-live. */
.wxs-live.is-offline { color: var(--bad); }
.wxs-live.is-offline .wxs-head-upd,
.wxs-live.is-offline .wxs-head-upd-d { color: var(--bad); }
@keyframes wxsPulse { 0% { box-shadow: 0 0 0 0 rgba(70,209,138,.55); } 70% { box-shadow: 0 0 0 7px rgba(70,209,138,0); } 100% { box-shadow: 0 0 0 0 rgba(70,209,138,0); } }
@keyframes wxsFlash { 0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(111,177,255,.7); } 50% { transform: scale(1.6); } 100% { transform: scale(1); box-shadow: 0 0 0 9px rgba(111,177,255,0); } }

/* temp on the top row; rotating line on its own row below, centred under temp+LED and
   WIDTH-LOCKED (width:0 + centred flex) so its changing width never shifts the menu */
.wxs-head-temp { grid-area: temp; display: inline-flex; align-items: center; white-space: nowrap; }
.wxs-head-main { font-size: 18px; font-weight: 800; color: var(--txt-0); font-variant-numeric: tabular-nums; }
.wxs-lang, .wxs-burger { grid-area: lang; justify-self: end; }   /* whichever is visible sits top-right */
.wxs-theme { grid-area: theme; justify-self: end; }              /* dark/light toggle, left of the lang button */
.wxs-head-rot { grid-area: rot; width: 0; overflow: visible; justify-self: center; justify-content: center;
  display: flex; align-items: center; gap: 4px; white-space: nowrap;
  font-size: 11px; font-weight: 700; color: var(--txt-2); font-variant-numeric: tabular-nums; transition: opacity .3s ease; }
.wxs-head-rot.is-swapping { opacity: 0; }   /* cross-fade dip while the rotating line swaps */
.wxs-head-rl { color: var(--txt-3); font-weight: 700; }   /* rotating-line title (Humidity/Wind/Rain) */
.wxs-head-wind { width: 12px; height: 12px; flex: none; }   /* wind view: arrow points in wind dir */
.wxs-clock, .wxs-menu-clock { display: none; }   /* live clock removed — the update-time stamp is enough */
.wxs-lang, .wxs-burger, .wxs-theme {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 32px; border-radius: 9px; cursor: pointer;
  background: var(--glass-bg-lo); border: 1px solid var(--glass-brd); color: var(--txt-1);
  font-size: 12px; font-weight: 700;
}
.wxs-lang:hover, .wxs-theme:hover { color: var(--txt-0); border-color: var(--glass-brd-hi); }
.wxs-theme .wxs-mi { width: 17px; height: 17px; opacity: 1; }
.wxs-burger { display: none; flex-direction: column; gap: 4px; }
.wxs-burger span { width: 16px; height: 2px; background: var(--txt-1); border-radius: 2px; }
/* burger-drawer extras (language switch + live clock + coords) — mobile only */
.wxs-menu-extra { display: none; }

/* ================= HEADER SUBBAR (latest update + coords) ================= */
.wxs-subbar {
  max-width: var(--maxw); margin: 7px auto 0; padding: 0 20px;
  display: flex; align-items: center; justify-content: space-between; gap: 12px 18px;
  font-size: 11.5px; color: var(--txt-2); flex-wrap: wrap;
  text-shadow: 0 1px 10px rgba(0,0,0,.55);   /* legible over the banner photo */
}
/* update time swapped to the RIGHT (geo goes left, below) and wrapped in a pill so it
   stays legible while scrolling over the banner photo */
.wxs-sub-update { order: 1; display: inline-flex; align-items: center; gap: 6px;
  color: var(--txt-0);   /* brighter than the subbar's muted default so the pill reads clearly */
  background: rgba(10,16,30,.72); border: 1px solid var(--glass-brd); border-radius: 999px; padding: 4px 12px; }
.wxs-sub-ic { width: 13px; height: 13px; flex: none; fill: none; stroke: var(--good); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.wxs-sub-update i { font-style: normal; font-weight: 600; }
.wxs-sub-update b { color: #6fe0a3; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: .2px; }
/* OFFLINE (≥15 min stale): the mini clock icon + the time turn red; the label
   and the date stay white — only the live/changing bits go red. */
.wxs-sub-update.is-offline .wxs-sub-ic { stroke: var(--bad); }
.wxs-sub-update.is-offline #wxs-sub-time-t { color: var(--bad); }
/* Lat/Long/Elev to the LEFT — wrapped in the SAME glass pill as the update
   stamp so the info reads clearly over the banner photo in both themes. */
.wxs-sub-geo { order: -1; display: inline-flex; align-items: center; gap: 6px;
  background: rgba(10,16,30,.72); border: 1px solid var(--glass-brd); border-radius: 999px; padding: 4px 12px;
  color: var(--txt-2); letter-spacing: .2px; }
.wxs-sub-geo b { color: var(--txt-1); font-weight: 600; }
/* tablet: keep the update-time pill pinned RIGHT even when the coords/elev pill is hidden
   (fitSubbar drops it when the two would wrap) — margin-auto right-aligns update, solo or paired. */
@media (min-width: 621px) and (max-width: 1024px) { .wxs-sub-update { margin-left: auto; } }
/* Desktop "Κεντρική Meteokav.gr" pill — mini glass pill (like the coords/update pills),
   absolutely centered in the subbar between them; desktop-only (mobile/tablet use the FAB). */
.wxs-sub-home { display: none; align-items: center; gap: 6px;
  background: rgba(10,16,30,.72); border: 1px solid var(--glass-brd); border-radius: 999px; padding: 4px 12px;
  color: var(--accent-2); font-weight: 600; letter-spacing: .2px; text-decoration: none;
  transition: color .15s ease, border-color .15s ease; }
.wxs-sub-home:hover { color: var(--txt-0); border-color: var(--glass-brd-hi); }
.wxs-sub-home__ic { width: 13px; height: 13px; flex: none; }
@media (min-width: 1120px) {
  .wxs-subbar { position: relative; }
  .wxs-sub-home { display: inline-flex; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); }
}

/* header rotating pill: small unit label (km/h, mm) — em-scaled so it shrinks with
   the pill; + the mobile-only "last update" stamp mirrored beside the live LED */
.wxs-head-u { font-size: .6em; font-weight: 700; opacity: .78; }
.wxs-head-upd { display: none; flex-direction: row; align-items: baseline; gap: 4px; color: var(--good); font-variant-numeric: tabular-nums; }
.wxs-head-upd-t { font-size: 11px; font-weight: 700; letter-spacing: .2px; }
.wxs-head-upd-d { font-size: 10px; font-weight: 600; color: var(--good); opacity: .72; }

/* ================= PLACE BANNER ================= */
.wxs-banner {
  position: relative; width: 100%; height: clamp(150px, 22vw, 270px); overflow: hidden;
  /* the photo (object-fit:cover) fills the banner opaquely; kept transparent +
     isolated so the ::after stroke-line/scrim compose in their own stacking context */
  background: transparent; isolation: isolate; z-index: 1;
  /* pulled up under the (transparent glass) header by banner.js so the photo
     reaches the very top of the page and the menu floats over it */
}
/* image stage. CURRENT design (2026-08-10): the photo ends at a CLEAN hard bottom
   EDGE finished with a stroke line (see .wxs-banner::after), NOT a soft fade. JS adds
   scroll-blur via `filter`.
   ── LEGACY soft bottom-fade — PRESERVED, not deleted (may revisit) ─────────────────
   The bottom used to be FEATHERED to transparent by a multi-stop mask so it dissolved
   into the page gradient (a soft Photoshop-style edge, no seam). It stopped at 96.5%
   (not 100%) to leave a transparent tail: on mobile the photo rides its own GPU layer
   (Ken-Burns pan) and a DPR 2–3 scroll re-composite could round mask vs image to
   different bounds, leaking a 1–3px un-feathered hairline — the tail absorbed it.
   To restore the fade: neutralise the stroke line in .wxs-banner::after and re-add
     -webkit-mask-image / mask-image:
       linear-gradient(to bottom, #000 0%, #000 56%, rgba(0,0,0,.94) 65%, rgba(0,0,0,.82) 72%, rgba(0,0,0,.64) 78%, rgba(0,0,0,.44) 84%, rgba(0,0,0,.26) 89%, rgba(0,0,0,.1) 93%, transparent 96.5%, transparent 100%);
   ──────────────────────────────────────────────────────────────────────────────── */
.wxs-banner__stage {
  position: absolute; inset: 0; z-index: 0; transition: filter .25s linear;
}
.wxs-banner__img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 55%;
  opacity: 0; transition: opacity 1.3s ease;
}
.wxs-banner__img.is-active { opacity: 1; }
/* Bottom finish (dark theme): a thin light-bar STROKE LINE at the photo's clean edge
   (brightest at centre, fading to the corners) + a soft glow off its centre + a
   bottom-LEFT scrim backing the station name (targeted, so the rest of the photo
   stays clean) + the corner vignette. Light theme swaps the line + scrim — see the
   light-theme override further down. (Legacy: the old overlay was a full-width
   bottom-darken feeding the soft fade; that fade is preserved commented on __stage.) */
.wxs-banner::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 1;
  background:
    linear-gradient(to right, rgba(150,190,255,0), rgba(155,196,255,.55) 27%, rgba(196,219,251,.85) 50%, rgba(155,196,255,.55) 73%, rgba(150,190,255,0)) center bottom / 100% 1px no-repeat,
    radial-gradient(54% 20px at 50% 100%, rgba(155,196,255,.20), transparent 72%),
    radial-gradient(126% 114% at 0% 114%, rgba(6,11,24,.90), rgba(6,11,24,.52) 28%, transparent 60%),
    radial-gradient(140% 130% at 50% 40%, transparent 62%, rgba(7,12,26,.28) 100%);
}
.wxs-banner__txt {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: 0 var(--gutter) 14px; max-width: var(--maxw); margin: 0 auto;
}
.wxs-banner__name {
  margin: 0; font-size: clamp(26px, 4.4vw, 46px); font-weight: 800; letter-spacing: -.02em;
  color: #fff; line-height: 1.05; text-shadow: 0 1px 2px rgba(0,0,0,.92), 0 2px 22px rgba(0,0,0,.72);
}
.wxs-banner__sub { display: flex; align-items: baseline; gap: 12px; margin-top: 4px; flex-wrap: wrap; }
.wxs-banner__area { font-size: clamp(13px, 2vw, 17px); font-weight: 600; color: rgba(228,237,250,.92); text-shadow: 0 1px 2px rgba(0,0,0,.90), 0 1px 12px rgba(0,0,0,.72); }
.wxs-banner__live {
  font-size: 12.5px; font-weight: 600; color: #eaf1fb; font-variant-numeric: tabular-nums;
  padding: 3px 10px; border-radius: 999px; background: rgba(10,16,30,.5);
  border: 1px solid rgba(150,180,230,.22); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.wxs-banner__live:empty { display: none; }
.wxs-banner__credit { position: absolute; right: 10px; bottom: 12px; z-index: 2; font-size: 9.5px; color: rgba(220,230,245,.5); text-shadow: 0 1px 4px rgba(0,0,0,.7); }
.wxs-banner__credit:empty { display: none; }
/* Boltek attribution mark — storm-tracker banner only. Same centred content-column
   geometry as .wxs-banner__txt but right-aligned, so it sits in the OPPOSITE
   (bottom-right) corner at a matching gutter/bottom inset to the name + live pill.
   Light-grey v2 mark + drop-shadow reads over the (bottom-darkened) photo on both themes. */
.wxs-banner__brand {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  max-width: var(--maxw); margin: 0 auto; padding: 0 var(--gutter) 24px;
  text-align: right; line-height: 0; pointer-events: none;
}
/* only the logo itself is clickable — the strip stays click-through */
.wxs-banner__brand a { display: inline-block; pointer-events: auto; transition: opacity .15s; }
.wxs-banner__brand a:hover { opacity: .82; }
.wxs-banner__boltek {
  height: clamp(21px, 3vw, 30px); width: auto; opacity: .92;
  filter: drop-shadow(0 1px 7px rgba(0,0,0,.6));
}
@media (prefers-reduced-motion: no-preference) {
  /* slow Ken-Burns pan; `will-change: transform` keeps the photo on its own GPU
     compositor layer so Chromium/WebKit animate it smoothly */
  .wxs-banner.is-loaded .wxs-banner__img {
    animation: wxsKenBurns 40s ease-in-out infinite alternate;
    will-change: transform; backface-visibility: hidden;
  }
  @keyframes wxsKenBurns { from { transform: scale(1.06) translate(0, 0); } to { transform: scale(1.14) translate(-1.6%, -1.2%); } }
}
/* Firefox janks this pan under WebRender (fine in Chrome), so show a STATIC photo
   there instead. Tagged in config.js → html.wxs-ff. Wins by specificity. */
html.wxs-ff .wxs-banner.is-loaded .wxs-banner__img { animation: none; will-change: auto; }

/* ================= DASHBOARD GRID ================= */
.wxs-main { max-width: var(--maxw); margin: 0 auto; padding: 6px var(--gutter) 40px; }
.wxs-dash {
  display: grid; gap: var(--gap);
  grid-template-columns: repeat(12, 1fr);
  margin-top: 10px;
}
.wxs-card { border-radius: var(--r-lg); padding: 18px; position: relative; overflow: hidden; }
/* ---- card status LEDs (top-right) — steady glow, short-flash on that card's
   value change (dashboard.js). Recessed: colour dot + dark seating ring. ---- */
.wxs-led { position: absolute; top: 13px; right: 14px; width: 9px; height: 9px; border-radius: 50%; z-index: 4; pointer-events: none;
  background: var(--led-c); box-shadow: 0 0 5px var(--led-glow); }   /* flat solid dot + soft glow */
/* LED colours match each parameter's graph colour */
.wxs-led--temp  { --led-c:#ff9f5a; --led-glow:rgba(255,159,90,.62); }   /* temperature — orange */
.wxs-led--wind  { --led-c:#46d18a; --led-glow:rgba(70,209,138,.6); }    /* wind — green */
.wxs-led--rain  { --led-c:#4f90e0; --led-glow:rgba(79,144,224,.62); }   /* rain — blue */
.wxs-led--humid { --led-c:#5fa8e6; --led-glow:rgba(95,168,230,.62); }   /* humidity — light blue */
.wxs-led--barom { --led-c:#9b8cf0; --led-glow:rgba(155,140,240,.62); }  /* barometer — purple */
@media (prefers-reduced-motion: no-preference) {
  .wxs-led.is-flash { animation: wxsLedFlash .6s ease-out; }
  @keyframes wxsLedFlash {
    0%   { box-shadow: 0 0 5px var(--led-glow); }
    28%  { box-shadow: 0 0 13px 3px var(--led-glow); transform: scale(1.28); filter: brightness(1.35); }
    100% { box-shadow: 0 0 5px var(--led-glow); }
  }
}
.wxs-card__title {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; font-weight: 700; letter-spacing: .6px; text-transform: uppercase;
  color: var(--txt-2); margin: 0 0 14px;
}
.wxs-card__ic {
  width: 16px; height: 16px; flex: none;
  fill: none; stroke: var(--accent-2); stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round; opacity: .9;
}

/* card spans */
.wxs-hero { grid-column: span 5; }   /* trimmed from 6; keeps the side-by-side metrics */
.wxs-wind { grid-column: span 3; }
.wxs-rain { grid-column: span 3; }
.wxs-cloudviz { grid-column: span 1; }   /* slim vertical cloud-base strip */

/* ===== cloud-base — slim full-bleed vertical sky strip ===== */
.wxs-cloudviz { padding: 0; overflow: hidden; }
.wxs-cloudviz__sky {
  position: relative; height: 100%; min-height: 214px; overflow: hidden;
  background: linear-gradient(to bottom, #1c539b 0%, #2f74bf 34%, #5c9fd9 66%, #93c5ea 100%);  /* day / sunny */
  transition: background .9s ease;
}
.wxs-cloudviz__sky.is-night {
  background: linear-gradient(to bottom, #081733 0%, #102c52 38%, #1b477e 70%, #2c5c94 100%);
}
.wxs-cloudviz__sky.is-twilight {  /* golden / blue hour */
  background: linear-gradient(to bottom, #1b2a5c 0%, #40376e 28%, #7a4f74 50%, #b56a63 68%, #dd8551 84%, #f4ac5c 100%);
}
/* night starfield — top of the sky, fades in only at night, behind everything else */
.wxs-cloudviz__stars {
  position: absolute; top: 0; left: 0; right: 0; height: 52%; z-index: 1; pointer-events: none;
  opacity: 0; transition: opacity .9s ease; background-repeat: no-repeat;
  background-image:
    radial-gradient(1px 1px at 15% 20%, #ffffff, transparent),
    radial-gradient(1px 1px at 67% 11%, rgba(255,255,255,.8), transparent),
    radial-gradient(1.4px 1.4px at 39% 31%, #ffffff, transparent),
    radial-gradient(1px 1px at 85% 37%, rgba(216,231,255,.75), transparent),
    radial-gradient(1px 1px at 25% 47%, rgba(255,255,255,.65), transparent),
    radial-gradient(1px 1px at 57% 55%, rgba(255,255,255,.7), transparent),
    radial-gradient(1.4px 1.4px at 79% 60%, rgba(255,255,255,.85), transparent),
    radial-gradient(1px 1px at 9% 63%, rgba(255,255,255,.55), transparent),
    radial-gradient(1px 1px at 92% 22%, rgba(255,255,255,.6), transparent),
    radial-gradient(1px 1px at 47% 70%, rgba(255,255,255,.5), transparent);
}
.wxs-cloudviz__sky.is-night .wxs-cloudviz__stars { opacity: 1; }
.wxs-cloudviz__sky.is-twilight .wxs-cloudviz__stars { opacity: .4; }   /* first stars at dusk */
/* a few brighter stars that gently twinkle */
.wxs-cloudviz__stars::before {
  content: ""; position: absolute; inset: 0; background-repeat: no-repeat;
  background-image:
    radial-gradient(1.4px 1.4px at 30% 14%, #ffffff, transparent),
    radial-gradient(1px 1px at 72% 27%, #ffffff, transparent),
    radial-gradient(1.4px 1.4px at 52% 42%, #ffffff, transparent),
    radial-gradient(1px 1px at 18% 38%, #ffffff, transparent);
  animation: wxs-twinkle 3.6s ease-in-out infinite;
}
@keyframes wxs-twinkle { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .wxs-cloudviz__stars::before { animation: none; opacity: .7; } }
/* sun (day) / moon (night) */
.wxs-cloudviz__orb {
  position: absolute; top: 15px; left: 50%; transform: translateX(-50%); width: 15px; height: 15px; border-radius: 50%;
  background: radial-gradient(circle at 45% 40%, #ffe7a3, #ffb43e); box-shadow: 0 0 11px 3px rgba(255,201,120,.4);
}
.wxs-cloudviz__orb.is-night {
  background: radial-gradient(circle at 62% 40%, #eef4ff 60%, #c2d2ee);
  box-shadow: 0 0 9px 2px rgba(210,225,255,.32); overflow: hidden;
}
.wxs-cloudviz__orb.is-night::after {
  content: ""; position: absolute; top: -4px; right: -5px; width: 13px; height: 13px; border-radius: 50%; background: #0a1a38;
}
.wxs-cloudviz__orb.is-twilight {  /* warm setting/rising sun */
  background: radial-gradient(circle at 45% 42%, #ffd693, #ff8f43);
  box-shadow: 0 0 15px 4px rgba(255,150,74,.5);
}
/* pressure-level reference lines (925 / 850 / 500 hPa) with the latest ECMWF temp */
.wxs-cloudviz__ticks { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.wxs-cloudviz__lvl { position: absolute; left: 0; right: 0; border-top: 1px dashed rgba(205,222,247,.16); }
.wxs-cloudviz__lvl-p { position: absolute; left: 5px; top: -7px; font-size: 9.5px; font-weight: 800; letter-spacing: .2px; color: rgba(206,222,247,.62); font-variant-numeric: tabular-nums; }
.wxs-cloudviz__lvl-p em { font-style: normal; font-size: .78em; font-weight: 700; opacity: .74; margin-left: 1.5px; letter-spacing: 0; }
.wxs-cloudviz__lvl-t { position: absolute; right: 5px; top: -9px; font-size: 13px; font-weight: 800; color: #eef4ff; font-variant-numeric: tabular-nums; text-shadow: 0 1px 4px rgba(0,8,24,.72); text-align: right; }
/* DAY only: on the bright sky the labels + readouts go WHITE and a touch brighter,
   carried by a firm dark halo so they pop against the blue (earlier they flipped dark /
   dimmed at brightness .82, which read poorly). Reference lines stay a soft dark. The
   temp keeps its colour-code — just lifted. Twilight & night keep the light base styling
   (twilight temps go plain white via JS). */
.wxs-cloudviz__sky.is-day .wxs-cloudviz__lvl { border-top-color: rgba(11,26,52,.4); }
.wxs-cloudviz__sky.is-day .wxs-cloudviz__lvl-p { color: #f5f9ff; text-shadow: 0 1px 2px rgba(3,12,32,.9), 0 0 3px rgba(3,12,32,.55); }
.wxs-cloudviz__sky.is-day .wxs-cloudviz__lvl-p em { opacity: .86; }
.wxs-cloudviz__sky.is-day .wxs-cloudviz__lvl-t { filter: brightness(1.12) saturate(1.12); text-shadow: 0 1px 2px rgba(3,10,26,.95), 0 0 4px rgba(3,10,26,.72); }
/* the cloud marker rides up/down to the current base height */
.wxs-cloudviz__cloud {
  position: absolute; left: 4px; right: 4px; top: 50%; transform: translateY(-50%); z-index: 4;
  display: flex; flex-direction: column; align-items: center; gap: 0; transition: top .8s cubic-bezier(.4,0,.2,1);
}
.wxs-cloudviz__cshape { width: 58%; max-width: 62px; height: auto; filter: drop-shadow(0 3px 7px rgba(0,0,0,.4)); }
.wxs-cloudviz__val { display: flex; align-items: baseline; gap: 1px; margin-top: -2px; }
.wxs-cloudviz__val b { font-size: 16px; font-weight: 800; color: #fff; font-variant-numeric: tabular-nums; text-shadow: 0 1px 6px rgba(0,10,30,.6); }
.wxs-cloudviz__val small { font-size: 9.5px; font-weight: 600; color: rgba(232,242,255,.8); }
/* ground line + station marker */
.wxs-cloudviz__ground { position: absolute; left: 0; right: 0; bottom: 0; height: 13%;
  background: linear-gradient(to bottom, rgba(46,96,148,0), rgba(20,52,40,.5) 55%, rgba(14,40,30,.88)); }
/* model-source credit + latest ECMWF run cycle for the upper-air temps */
.wxs-cloudviz__src { position: absolute; left: 0; right: 0; bottom: 14px; text-align: center;
  font-size: 7.5px; font-weight: 700; letter-spacing: .6px; text-transform: uppercase;
  color: rgba(206,222,246,.5); text-shadow: 0 1px 2px rgba(0,8,24,.6); }
.wxs-cloudviz__run { position: absolute; left: 0; right: 0; bottom: 3px; text-align: center;
  font-size: 8.5px; font-weight: 700; color: rgba(212,227,249,.66); font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 2px rgba(0,8,24,.6); }
/* per-level readout extras: the % unit (humidity) + the wind flow-arrow & km/h unit (wind) */
.wxs-cloudviz__lvl-t small { font-size: .68em; font-weight: 700; opacity: .82; margin-left: .5px; }
.wxs-cvwind { width: 11px; height: 11px; display: inline-block; vertical-align: -1.5px; margin-right: 1px; }
/* wind km/h unit — tiny, dim, on its own line UNDER the speed (higher specificity than
   the generic 'small' rule above so it goes block + smaller) */
.wxs-cloudviz__lvl-t .wxs-cvu { display: block; font-size: .55em; font-weight: 700; opacity: .64; line-height: 1; margin: -1px 0 0; letter-spacing: .2px; }
/* parameter toggle — 3 mini icon buttons at the base of the tube (temp / hum / wind) */
.wxs-cloudviz__params {
  position: absolute; left: 0; right: 0; bottom: 40px; z-index: 5;   /* raised for breathing room above the ECMWF credit */
  display: flex; justify-content: center; gap: 4px;
}
.wxs-cvparam {
  width: 20px; height: 20px; padding: 0; display: grid; place-items: center; cursor: pointer;
  border-radius: 6px; border: 1px solid rgba(150,180,230,.26); background: rgba(9,18,38,.5);
  color: rgba(214,228,250,.55); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  transition: color .15s, background .15s, border-color .15s;
}
.wxs-cvparam svg { width: 13px; height: 13px; display: block; }
.wxs-cvparam:hover { color: #eaf3ff; border-color: rgba(150,190,255,.5); }
.wxs-cvparam.is-on { color: #eef6ff; background: rgba(79,144,224,.5); border-color: rgba(150,190,255,.7);
  box-shadow: 0 0 8px rgba(79,144,224,.4); }
.wxs-cvparam:focus-visible { outline: none; box-shadow: 0 0 0 2px rgba(120,170,240,.55); }
.wxs-hum-col { grid-column: span 4; display: flex; flex-direction: column; gap: var(--gap); }  /* hum/baro + fire index */
.wxs-hum-col .wxs-humbaro { flex: 1; }        /* humbaro shrinks to make room for the slim fire card */
.wxs-otd-col { grid-column: span 4; display: flex; flex-direction: column; gap: var(--gap); }
.wxs-misc-col { grid-column: span 4; display: flex; flex-direction: column; gap: var(--gap); }
/* Fire Danger — slim one-line card under Humidity & Barometer */
.wxs-firewx { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 18px; }
/* FIRE DANGER card DISABLED 2026-09-07 (user: hide the fire index completely, every
   theme + breakpoint). Reversible: delete this one rule + restore WXS.firewx.init() in
   index.php. Nothing else shifts — the humidity + barometer cards (flex:1) just fill the
   column again as they did before the fire card was added; on mobile it's an ordered grid
   item so removing it leaves the others' order intact. */
.wxs-firewx { display: none; }
.wxs-firewx__lbl { display: inline-flex; align-items: center; gap: 8px; min-width: 0; font-size: 11px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--txt-2); }
.wxs-firewx__lbl .wxs-card__ic { width: 17px; height: 17px; flex: none; margin: 0; opacity: .9; }
.wxs-firewx__out { display: inline-flex; align-items: baseline; gap: 7px; white-space: nowrap; }
.wxs-firewx__cat { font-size: 14px; font-weight: 800; }
.wxs-firewx__src { font-size: 8.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--txt-3); opacity: .65; }

/* ---- key/value rows ---- */
.wxs-rows { display: flex; flex-direction: column; gap: 9px; }
.wxs-kv { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; border-bottom: 1px dashed rgba(120,150,200,.12); padding-bottom: 7px; }
.wxs-kv:last-child { border-bottom: 0; padding-bottom: 0; }
.wxs-kv i { font-style: normal; font-size: 12.5px; color: var(--txt-2); }
.wxs-kv b { font-size: 14.5px; font-weight: 700; color: var(--txt-0); font-variant-numeric: tabular-nums; }
.wxs-kv b u { text-decoration: none; font-size: 11px; color: var(--txt-2); font-weight: 600; }
.wxs-rows--lg .wxs-kv b { font-size: 17px; }

/* ================= HERO ================= */
.wxs-hero { padding: 16px 22px 20px; }
.wxs-hero::before {
  content: ""; position: absolute; inset: -30% 45% auto -10%; height: 80%;
  /* soft glow via the gradient itself — a nested blur() FILTER inside this
     backdrop-filter card made the hero content intermittently vanish on scroll
     (a Chromium compositing bug), so no filter here */
  background: radial-gradient(closest-side, var(--temp-glow), transparent 72%); pointer-events: none;
  /* SILENCED 2026-09-11 (user: not needed for now) — the temperature colour
     "leak" behind the conditions/temp box is off in every theme. The gradient
     above is kept intact; to REVIVE, delete the next line (light re-hides it via
     its own :root[data-theme="light"] .wxs-hero::before rule further down). */
  display: none;
}
/* head: condition icon (upper-left) + title + condition text */
.wxs-hero__head { display: flex; align-items: center; gap: 13px; margin-bottom: 14px; position: relative; }
.wxs-hero__icon { width: 64px; height: 64px; flex: none; filter: drop-shadow(0 5px 14px rgba(0,0,0,.35)); }
.wxs-hero__icon .wxi { width: 100%; height: 100%; }
.wxs-hero__headtxt { display: flex; flex-direction: column; min-width: 0; }
.wxs-hero__kicker { font-size: 11px; font-weight: 700; letter-spacing: .6px; text-transform: uppercase; color: var(--txt-2); }
.wxs-hero__cond { font-size: 19px; font-weight: 700; color: var(--txt-0); margin-top: 2px; }
.wxs-cloud-obs { display: flex; align-items: center; gap: 5px; margin-top: 4px; font-size: 12px; font-weight: 600; color: var(--warn); line-height: 1.2; }
.wxs-cloud-obs:empty { display: none; }
.wxs-bolt-ic { width: 14px; height: 14px; flex: none; fill: #ffd24a; filter: drop-shadow(0 0 4px rgba(255,180,84,.55)); }
@media (prefers-reduced-motion: no-preference) {
  .wxs-bolt-ic { animation: wxsBoltFlick 2.6s steps(1) infinite; }
  @keyframes wxsBoltFlick { 0%, 88%, 100% { opacity: 1; } 90% { opacity: .25; } 92% { opacity: 1; } 95% { opacity: .55; } }
}

.wxs-hero__body { display: flex; align-items: flex-start; gap: 18px; min-width: 0; }
/* keep the temp/metrics on their own stable paint layer so they don't drop out
   during scroll repaints inside the backdrop-filtered card */
.wxs-hero__main { position: relative; flex: 1; min-width: 0; transform: translateZ(0); }

/* vertical analog thermometer */
.wxs-thermo { width: 61px; flex: none; align-self: stretch; display: flex; align-items: flex-start; margin-top: 6px; }   /* +5px thicker (was 56) */
.wxs-thermo-svg { width: 100%; height: 200px; overflow: visible; }   /* height nudged 196→200 so the +5px width isn't capped by the SVG aspect ratio */
.wxs-th-tube { fill: rgba(8,14,30,.55); stroke: var(--glass-brd); stroke-width: 1.4; }
.wxs-th-merc { transition: fill .8s ease; filter: drop-shadow(0 0 4px var(--temp-glow)); }
.wxs-th-tick { stroke: var(--txt-3); stroke-width: 1.2; }
.wxs-th-lbl { fill: var(--txt-2); font-size: 9px; font-family: var(--font); font-variant-numeric: tabular-nums; }
/* daily min/max markers (left of the tube): warm red = high, cool blue = low */
.wxs-th-mark--max { fill: #ff6b6b; }
.wxs-th-mark--min { fill: #6fb1ff; }
.wxs-th-marklbl { font-family: var(--font); font-size: 9px; font-weight: 700; font-variant-numeric: tabular-nums; }

/* temp box: temperature number + trends. Mobile = trends beside temp;
   desktop = trends stacked below (set in the media query). */
.wxs-hero__tempbox { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.wxs-hero__temprow { display: flex; align-items: flex-start; gap: 4px; align-self: center; }   /* centre the temp within its column */
.wxs-hero__temp {
  font-size: clamp(44px, 6.4vw, 68px); font-weight: 800; line-height: .9; letter-spacing: -2px;
  color: var(--temp-color); font-variant-numeric: tabular-nums;
  text-shadow: 0 4px 22px var(--temp-glow);
}
.wxs-hero__deg { font-size: 22px; font-weight: 700; color: var(--txt-2); margin-top: 6px; }

/* top: temperature box + metrics (feels / dew / wet) beside it */
.wxs-hero__top { display: flex; flex-direction: column; gap: 14px; margin-bottom: 14px; }
.wxs-hero__metrics { display: flex; flex-direction: column; gap: 9px; }

/* feels like — bigger, + heat word */
.wxs-hero__feels { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.wxs-hero__feelsrow { display: inline-flex; align-items: baseline; gap: 8px; }
.wxs-hero__feels i { font-style: normal; font-size: 13.5px; color: var(--txt-2); white-space: nowrap; }
.wxs-hero__feels b { font-size: 20.8px; font-weight: 800; color: var(--txt-0); font-variant-numeric: tabular-nums; }
.wxs-heatword { align-self: center; font-size: 11px; font-weight: 700; color: var(--accent-2); background: var(--accent-soft); padding: 3px 11px; border-radius: 999px; border: 1px solid transparent; white-space: nowrap; text-align: center; line-height: 1.25; }
.wxs-heatword:empty { display: none; }

/* dew point / wet bulb rows */
.wxs-metric { display: flex; align-items: baseline; gap: 8px; white-space: nowrap; }
.wxs-metric[hidden] { display: none; }   /* conditional heat-index / wind-chill rows */
.wxs-metric i { font-style: normal; font-size: 12px; color: var(--txt-2); }
.wxs-metric b { font-size: 15px; font-weight: 700; color: var(--txt-0); font-variant-numeric: tabular-nums; }

/* max/min mini table (Today | Yesterday) */
.wxs-mm {
  display: grid; grid-template-columns: auto 1fr 1fr; gap: 7px 16px; align-items: center;
  padding-top: 12px; border-top: 1px dashed rgba(120,150,200,.14); max-width: 360px;
}
.wxs-mm__h { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--txt-2); }
.wxs-mm__rl { font-size: 12px; font-weight: 700; }
.wxs-mm__hi { color: #f08a78; }
.wxs-mm__lo { color: #6fb1ff; }
.wxs-mm__cell { display: flex; align-items: baseline; gap: 6px; }
.wxs-mm__cell b { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }
.wxs-mm__cell.hi b { color: #f08a78; }
.wxs-mm__cell.lo b { color: #6fb1ff; }
.wxs-mm__cell u { text-decoration: none; font-size: 10px; color: var(--txt-3); font-variant-numeric: tabular-nums; }
/* Dark-theme readability (2026-08-10): these small secondary figures read too faint
   at --txt-3 on the dark ground — the max/min TIMES (Today/Yesterday) and the record
   YEARS/DATES in the OTD ("Σαν Σήμερα") + All-Time ("Απόλυτα Ρεκόρ") cards. Lift to
   --txt-2 on DARK only; light keeps its own (already-legible) --txt-3 mapping. */
:root[data-theme="dark"] .wxs-mm__cell u,
:root[data-theme="dark"] .wxs-otd-yr,
:root[data-theme="dark"] .wxs-otd-date,
:root[data-theme="dark"] .wxs-alltime .wxs-at-cell u { color: var(--txt-2); }
/* Narrow phones (Samsung A54 ~360px, iPhone 12/13 mini, SE): the Today/Yesterday
   min-max grid sits in the ~200px column beside the tall thermometer, so its
   label + two value/time cells overflow the card's right edge and the last time
   digits get clipped (card is overflow:hidden). Tighten the column gap + fonts so
   it fits. Standard phones (>=390px) and desktop have room and are left untouched. */
@media (max-width: 388px) {
  .wxs-mm { gap: 6px 7px; }
  .wxs-mm__cell { gap: 4px; }
  .wxs-mm__h { font-size: 9.5px; letter-spacing: .2px; }
  .wxs-mm__rl { font-size: 11px; }
  .wxs-mm__cell b { font-size: 13.5px; }
  .wxs-mm__cell u { font-size: 9px; }
}

/* DESKTOP: metrics (feels / dew / wet) sit BESIDE the big temp with a
   divider; trends drop below the temp; Max/Min sits below the whole row.
   Mobile (<=620) stacks the metrics under the temp; trends beside temp. */
@media (min-width: 621px) {
  .wxs-hero__top { flex-direction: row; align-items: center; gap: 22px; }
  .wxs-hero__tempbox { flex: none; flex-direction: column; align-items: flex-start; gap: 10px; }
  .wxs-hero__trends { align-self: flex-start; }
  .wxs-hero__metrics { flex: none; padding-left: 22px; border-left: 1px dashed rgba(120,150,200,.16); }
}

.wxs-hero__trends { display: flex; flex-direction: column; gap: 6px; align-self: center; }
.wxs-trend {
  align-self: flex-start; font-size: 12.5px; font-weight: 700;
  padding: 3px 10px; border-radius: 999px; background: var(--glass-bg-lo); white-space: nowrap;
}
.wxs-trend:empty { display: none; }
.wxs-trend span { font-weight: 500; color: var(--txt-2); font-size: 11px; margin-left: 3px; }
.wxs-trend.up { color: var(--good); }
.wxs-trend.down { color: var(--bad); }
.wxs-trend.flat { color: var(--txt-2); }

/* ================= small rows (shared) ================= */
.wxs-rows--sm { gap: 6px; }
.wxs-rows--sm .wxs-kv i { font-size: 11.5px; }
.wxs-rows--sm .wxs-kv b { font-size: 13px; }

/* ================= WIND ================= */
.wxs-wind__top {
  display: flex; align-items: center; justify-content: center; gap: 14px;
}
/* current Beaufort force + status text (separates current from historic) */
.wxs-wind__bft {
  text-align: center; font-size: 14px; font-weight: 700; color: var(--txt-1);
  margin-top: 10px; padding-bottom: 13px; margin-bottom: 12px;
  border-bottom: 1px dashed rgba(120,150,200,.14);
}
.wxs-compass { width: 104px; height: 104px; flex: none; }
.wxs-comp-ring { fill: rgba(10,18,38,.5); stroke: var(--glass-brd); stroke-width: 1.5; }
.wxs-comp-ring2 { fill: none; stroke: rgba(120,150,200,.1); stroke-width: 1; }
.wxs-comp-mark { stroke: var(--txt-3); stroke-width: 1.2; opacity: .55; }
.wxs-comp-lbl { fill: var(--txt-2); font-size: 11px; font-weight: 700; text-anchor: middle; dominant-baseline: middle; font-family: var(--font); }
.wxs-comp-hub { fill: var(--txt-2); }   /* centre hub matches the N/E/S/W letter colour */
.wxs-comp-needle, .wxs-comp-dom { transform-origin: 60px 60px; transition: transform 1s cubic-bezier(.34,1.3,.5,1), opacity .3s; }

.wxs-wind__big { flex: 1; min-width: 0; text-align: center; }
.wxs-wind__dir { font-size: 17px; font-weight: 800; color: var(--txt-0); margin-bottom: 8px; }
.wxs-wind__bigrow { display: flex; gap: 14px; justify-content: center; align-items: flex-start; }
.wxs-bigval { display: flex; flex-direction: column; align-items: center; line-height: 1; }
.wxs-bigval__num { font-size: 26px; font-weight: 800; color: var(--txt-0); font-variant-numeric: tabular-nums; transition: color .4s ease; }
.wxs-bigval-sep { color: var(--txt-3); font-size: 24px; font-weight: 700; line-height: 26px; }
.wxs-bigval__u { font-size: 10.5px; color: var(--txt-2); font-weight: 600; margin-top: 2px; }
.wxs-bigval label { font-size: 11px; color: var(--txt-2); margin-top: 3px; }

/* ================= RAIN ================= */
.wxs-rain__top {
  display: flex; align-items: center; gap: 14px;
  padding-bottom: 12px; margin-bottom: 11px; border-bottom: 1px dashed rgba(120,150,200,.14);
}
.wxs-rain__hero { flex: none; }
.wxs-rain__big { font-size: 36px; font-weight: 800; color: var(--accent-2); font-variant-numeric: tabular-nums; line-height: 1; }
/* 3-digit daily rain (>=100mm) shrinks so the rate column keeps its space */
.wxs-rain__big.is-3d { font-size: 27px; }
.wxs-rain__big.is-3d + .wxs-rain__unit { font-size: 13px; }
.wxs-rain__unit { font-size: 15px; color: var(--txt-2); font-weight: 600; margin-left: 4px; }
.wxs-rain__hero small { display: block; font-size: 12px; color: var(--txt-2); margin-top: 4px; }
.wxs-rain__rates { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 7px; }
.wxs-rain__rates .wxs-kv i { font-size: 12px; white-space: nowrap; }
.wxs-rain__rates .wxs-kv b { font-size: 12.5px; white-space: nowrap; }
.wxs-kv--accent i { color: var(--accent-2); font-weight: 700; }
.wxs-kv--accent b { color: var(--accent-2); }
/* Storm Rain emphasised — must out-specify both `.wxs-rows--sm .wxs-kv b`(13px)
   and a later storm-tracker `.wxs-kv b`(txt-1 colour) that leaks onto the dash */
.wxs-rows--sm .wxs-kv--accent b { font-size: 17.6px; color: var(--accent-2); }
.wxs-rows--sm .wxs-kv--accent i { color: var(--accent-2); }
/* "N rain days in <month>" sentence below the rain rows */
.wxs-raindays { margin-top: 4px; font-size: 12px; color: var(--txt-2); text-align: center; }
.wxs-raindays:empty { display: none; }
.wxs-raindays b { color: var(--accent-2); font-weight: 700; font-variant-numeric: tabular-nums; }

/* ================= HUMIDITY & BAROMETER ================= */
/* single vertical list; a divider line separates the humidity & baro groups */
.wxs-hb3 { display: flex; flex-direction: column; gap: 9px; }
.wxs-hb3 .wxs-kv { border-bottom: 0; padding: 0; }
.wxs-hb3__sep { border-top: 1px dashed rgba(120,150,200,.22); margin: 2px 0; }
/* vertically centre all the humidity/baro rows in the stretched card */
.wxs-humbaro { display: flex; flex-direction: column; }
.wxs-humbaro .wxs-hb3 { flex: 1; justify-content: center; }
.wxs-kv.wxs-hb3__mx i { color: #ff8a78; }   /* max — red */
.wxs-kv.wxs-hb3__mn i { color: #6fb1ff; }   /* min — blue */
/* max/min value numbers ~20% smaller than the main readings */
.wxs-hb3__mx .wxs-kv__v b, .wxs-hb3__mn .wxs-kv__v b { font-size: 11.5px; }
.wxs-kv__v { display: inline-flex; align-items: baseline; gap: 6px; }

/* ---- Humidity + Barometer split cards (in .wxs-hum-col, above the fire card) ----
   prominent value + graduated bar on the left, max/min stacked on the right.
   Keeps the dashboard's own font (no mono) — value size matches .wxs-bigval__num. */
.wxs-hum-col .wxs-humid, .wxs-hum-col .wxs-barom { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.wxs-hbx { flex: 1; display: flex; align-items: center; gap: 16px; margin-top: 6px; flex-wrap: wrap; }
.wxs-hbx__main { flex: 1 1 120px; min-width: 0; container-type: inline-size; }  /* container for the baro trend/rate cqi font (safe: main is flex-sized, not content-sized, at every width) */
.wxs-hbx__val { display: flex; align-items: baseline; gap: 3px; }
.wxs-hbx__val b { font-size: 26px; font-weight: 800; color: var(--txt-0); font-variant-numeric: tabular-nums; line-height: 1; letter-spacing: -.01em; }
.wxs-hbx__u { font-size: 14px; color: var(--txt-2); font-weight: 600; }   /* unit smaller than the value */
.wxs-hbx__bar { position: relative; height: 7px; border-radius: 5px; margin-top: 11px; overflow: hidden;
  background: rgba(122,150,200,.14); box-shadow: inset 0 1px 2px rgba(0,0,0,.4); }
/* the fill carries the FULL-range pastel colour-scale; a clip-path reveals it up to
   the current value (so the colour at the fill's leading edge = the value's colour) */
.wxs-hbx__bar i { position: absolute; inset: 0; border-radius: 5px; clip-path: inset(0 100% 0 0); -webkit-clip-path: inset(0 100% 0 0);
  transition: -webkit-clip-path .7s cubic-bezier(.2,.7,.3,1), clip-path .7s cubic-bezier(.2,.7,.3,1); }
.wxs-hbx__ticks { position: absolute; inset: 0; background-image: repeating-linear-gradient(90deg, rgba(6,10,22,.5) 0 1px, transparent 1px 10%); }
/* Humidity 1→100% : dry orange → yellow → greens → slate → violet (pastel) */
.wxs-humid .wxs-hbx__bar i { background: linear-gradient(90deg, #f0a45c 0%, #f2c95e 15%, #d4dd6e 33%, #9bd182 50%, #5cbb84 70%, #3f9c7e 86%, #5d84a6 93%, #9d8cf0 100%); }
/* Barometer 970→1045 hPa : indigo → blue → cyan → pale → green → yellow → orange → red (pastel) */
.wxs-barom .wxs-hbx__bar i { background: linear-gradient(90deg, #7a72c8 0%, #6f9fe0 19%, #83cfe6 35%, #dbe9f0 43%, #83d08c 51%, #c6dc74 60%, #f0d266 68%, #f2a860 77%, #ec7e68 89%, #d95f68 100%); }
/* trend + rate sit right under the colour bar (in .wxs-hbx__main), close to it. The
   hum/baro column is narrow (the gauge + min/max squeeze it to ~132px desktop / ~83px
   mobile) so at a fixed size the longest label ("▼ Καθοδική · -1.2 hPa/hr", ~156px)
   wrapped. The font scales with the column width (cqi = % of .wxs-hbx__main) + nowrap so
   it always fits ONE line — ~12.5px on wide columns down to ~6.5px on the tiny mobile
   half-card. */
.wxs-barom__sub { font-size: clamp(6.5px, 7.6cqi, 12.5px); white-space: nowrap; color: var(--txt-2); margin-top: 9px; display: flex; align-items: center; gap: 6px; font-variant-numeric: tabular-nums; }
.wxs-barom__mid { opacity: .5; }
.wxs-hbx__mm { flex: none; display: flex; flex-direction: column; gap: 7px; }
.wxs-hbx__mm .wxs-kv { border-bottom: 0; padding: 0; flex-direction: column; align-items: flex-end; gap: 1px; }
.wxs-hbx__mm .wxs-kv i { font-size: 9.5px; }
.wxs-hbx__mm .wxs-kv__v em { font-size: 8.5px; color: var(--txt-3); font-style: normal; }
/* ---- EXPERIMENTAL analogue gauge (humidity/barometer) — DESKTOP ONLY ----
   Sits between the reading and the min/max, filling the dead space so the box feels
   more informative. Hidden ≤1024px, so mobile/tablet keep the current [reading|min-max]
   layout untouched. Added as a flex sibling, it naturally narrows the colour bar. */
.wxs-hbx__gauge { flex: none; width: 152px; align-self: center; }
.wxs-gauge { width: 100%; height: auto; display: block; overflow: visible; transform: translateY(-6px); }   /* nudge the dial up for breathing space above the MIN/MAX row (visual only — no layout/card-size change) */
.wxs-gauge__track { fill: none; stroke: var(--glass-brd); stroke-width: 6; stroke-linecap: round; }
.wxs-gauge__fill  { fill: none; stroke: var(--accent-2); stroke-width: 6; stroke-linecap: round;
  transition: stroke-dashoffset .8s cubic-bezier(.34,1.3,.5,1), stroke .5s ease; }   /* stroke re-coloured per-value by JS; the value-arc sweeps via animated stroke-dashoffset (matches the needle easing) */
.wxs-gauge__tick { stroke: var(--txt-3); stroke-width: 1.2; stroke-linecap: round; opacity: .55; }
.wxs-gauge__lbl { fill: var(--txt-1); font-size: 7.5px; font-weight: 700; font-family: var(--font); text-anchor: middle; font-variant-numeric: tabular-nums; }
.wxs-gauge__needle { transform-box: view-box; transform-origin: 60px 60px;
  transition: transform .8s cubic-bezier(.34,1.3,.5,1); }
/* one-time FLUID load fill: a slower, smooth ease-out (no spring overshoot) for the arc + needle as they
   sweep from the left end to the current value on first load; the class is removed ~1.5s later so live
   updates fall back to the quick spring above. */
.wxs-gauge--load .wxs-gauge__fill { transition: stroke-dashoffset 1.4s cubic-bezier(.25,.8,.35,1), stroke .5s ease; }
.wxs-gauge--load .wxs-gauge__needle { transition: transform 1.4s cubic-bezier(.25,.8,.35,1); }
.wxs-gauge__needle path { fill: var(--txt-0); }
.wxs-gauge__hub { fill: var(--txt-2); }
/* day max/min pointers on the rim (red = max, blue = min), rotated to their value */
.wxs-gauge__mk { transform-box: view-box; transform-origin: 60px 60px; transition: transform .8s cubic-bezier(.34,1.3,.5,1); }
.wxs-gauge__mk path { stroke: rgba(4,8,18,.55); stroke-width: .5; paint-order: stroke; }   /* thin dark outline so the marker pops off the coloured arc */
.wxs-gauge__mk--mx path { fill: #ff6b6b; }
.wxs-gauge__mk--mn path { fill: #6fb1ff; }
/* MIN / MAX label + "value · time" under the two dial ends (blue = min at the left, red = max at the right) */
.wxs-gauge__ends { display: flex; justify-content: space-between; align-items: flex-start; padding: 0 2px; }
.wxs-gauge__end { display: flex; flex-direction: column; line-height: 1.16; }
.wxs-gauge__end--mn { align-items: flex-start; text-align: left; }
.wxs-gauge__end--mx { align-items: flex-end; text-align: right; }
.wxs-gauge__end i { font-size: 8px; font-style: normal; letter-spacing: .3px; font-weight: 700; }
.wxs-gauge__end b { font-size: 9px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.wxs-gauge__end--mn i { color: #6fb1ff; opacity: .9; } .wxs-gauge__end--mn b { color: #6fb1ff; }
.wxs-gauge__end--mx i { color: #ff8a78; opacity: .9; } .wxs-gauge__end--mx b { color: #ff8a78; }
@media (max-width: 1024px) { .wxs-hbx__gauge { display: none; } }   /* mobile/tablet: no gauge; .wxs-hbx__mm shows min/max instead */
@media (min-width: 1025px) { .wxs-hbx__mm { display: none; } }
/* mini trend arrow (rising green / falling red) on dew, humidity, barometer */
.wxs-tarrow { font-size: 9px; line-height: 1; }
.wxs-tarrow:empty { display: none; }
.wxs-tarrow.up { color: #46d18a; }
.wxs-tarrow.down { color: #ff6b6b; }
.wxs-kv__v em { font-style: normal; font-size: 10px; color: var(--txt-3); font-weight: 600; font-variant-numeric: tabular-nums; }

/* ================= SUN & MOON (Διάφορα) ================= */
.wxs-sunmoon__grid { display: grid; grid-template-columns: 1fr 120px; gap: 16px; align-items: center; }
/* cloud base / solar / uv footer inside the misc box */
.wxs-misc-extra {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px;
}
.wxs-misc-extra > div { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.wxs-misc-extra i { font-style: normal; font-size: 11px; color: var(--txt-2); white-space: nowrap; }
.wxs-misc-extra b { font-size: 14.5px; font-weight: 700; color: var(--txt-0); font-variant-numeric: tabular-nums; }
/* AQI value + its category word side by side (status moved next to the value) */
.wxs-aqi-val { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; min-width: 0; }
.wxs-misc-extra .wxs-aqi-cat { font-size: 11.5px; font-weight: 700; line-height: 1.15; }   /* category word, coloured by JS */
.wxs-moonbox { text-align: center; }
.wxs-moon { width: 92px; height: 92px; filter: drop-shadow(0 4px 14px rgba(0,0,0,.4)); }
.wxs-moon-name { font-size: 12px; font-weight: 600; color: var(--txt-1); margin-top: 4px; }
.wxs-moon-bright { font-size: 11px; color: var(--txt-2); }
.wxs-moon-bright span { color: var(--txt-0); font-weight: 700; }
.wxs-moon-bright i { font-style: normal; }

/* compact Astronomy box (trivial info → smaller box + contents) */
.wxs-astro { padding: 14px; }
.wxs-astro .wxs-card__title { margin-bottom: 9px; }
.wxs-astro .wxs-sunmoon__grid { grid-template-columns: auto 120px; gap: 22px; justify-content: center; align-items: center; }
/* sun/moon times as a tight 2-col grid (label | value) → small, consistent gap, values aligned */
.wxs-astro .wxs-sun { display: grid; grid-template-columns: auto auto; column-gap: 16px; row-gap: 8px; align-items: baseline; }
.wxs-astro .wxs-sun .wxs-kv { display: contents; }
.wxs-astro .wxs-sun .wxs-kv i { font-size: 11px; }
.wxs-astro .wxs-sun .wxs-kv b { font-size: 12px; text-align: left; }
/* bigger moon phase + its caption */
.wxs-astro .wxs-moon { width: 78px; height: 78px; }
.wxs-astro .wxs-moon-name { font-size: 11.5px; margin-top: 4px; line-height: 1.15; }
.wxs-astro .wxs-moon-bright { font-size: 10px; }

/* ================= 1-HOUR GRAPHS ================= */
.wxs-graphs { max-width: var(--maxw); margin: 28px auto 0; padding: 0 var(--gutter); }
.wxs-graphs__head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.wxs-graphs__title { font-size: clamp(17px, 2vw, 21px); font-weight: 800; color: var(--txt-0); margin: 0; letter-spacing: -.2px; }
.wxs-graphs__sub { font-size: 12.5px; color: var(--txt-2); }

/* ===== section headline — icon + mini-title + trailing rule (reusable) =====
   A compact, professional section label: an accent icon-chip + an uppercase
   accent title + an optional muted sub, then a thin rule that runs to the edge.
   Fully theme-token-based, so it reads correctly in navy / graphite / light. */
.wxs-shead { display: flex; align-items: center; gap: 10px; margin-bottom: 15px; flex-wrap: wrap; }
.wxs-shead__ic { flex: none; display: grid; place-items: center; width: 25px; height: 25px; border-radius: 7px;
  background: var(--accent-soft); color: var(--accent-2); }
.wxs-shead__ic svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.wxs-shead__t { margin: 0; font-size: 12px; font-weight: 800; letter-spacing: 1.4px; text-transform: uppercase;
  color: var(--accent-2); white-space: nowrap; }
.wxs-shead__sub { flex: none; font-size: 11px; font-weight: 600; color: var(--txt-2); white-space: nowrap; }
.wxs-shead__sub::before { content: "·"; margin-right: 7px; color: var(--txt-3); }
.wxs-shead__rule { flex: 1; min-width: 24px; height: 1px;
  background: linear-gradient(90deg, var(--glass-brd-hi), var(--glass-brd) 55%, transparent); }
/* the "full forecast" button rides at the far right, after the rule */
.wxs-shead .wxs-fc-btn { flex: none; }
/* compact variant on the media-row box heads (camera/satellite/lightning): the
   box's own 9px gap handles spacing (no bottom margin), a smaller chip, tighter
   tracking, and an ellipsis safety-net so a long title ("Ανιχνευτής Κεραυνών")
   never overflows the narrow stacked boxes. */
.wxs-media-box .wxs-shead { margin: 0; gap: 8px; flex-wrap: nowrap; }
.wxs-media-box .wxs-shead__ic { width: 22px; height: 22px; border-radius: 6px; }
.wxs-media-box .wxs-shead__ic svg { width: 13px; height: 13px; }
.wxs-media-box .wxs-shead__t { font-size: 12px; letter-spacing: .7px; flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.wxs-media-box .wxs-shead__rule { min-width: 14px; }
/* page-header variant (subpages): the headline fills between the back button and any
   right-side controls (interval toggle etc.). The title stays a notch larger than a
   section label for page-level hierarchy — still uppercase accent, but reduced from the
   old 20-28px page H1 for a more minimal feel. */
.wxs-fcpage__head .wxs-shead { flex: 1 1 auto; margin: 0; min-width: 0; }
.wxs-shead--page .wxs-shead__t { font-size: clamp(15px, 1.9vw, 19px); letter-spacing: .8px; }
/* mobile: subpage headline on one row with the home mini-button on the RIGHT,
   aligned with the title. The descriptive sub is dropped here for a clean, minimal
   header; any right-side controls (wxgraphs interval toggle) still wrap below. */
@media (max-width: 620px) {
  .wxs-fcpage__head { flex-wrap: wrap; align-items: center; }
  .wxs-fcpage__head .wxs-shead { order: 1; flex: 1 1 auto; min-width: 0; margin: 0; }
  .wxs-fcpage__head .wxs-back { order: 2; margin: 0 0 0 6px; }
  .wxs-shead--page .wxs-shead__sub { display: none; }
  .wxs-shead--page .wxs-shead__t { white-space: normal; }
}
/* exception — the FORECAST subpage keeps its sub on mobile (it carries the live WXSIM
   issue date/time, worth showing): un-hide it and drop it onto its own line under the
   title, indented to align with it. The shead gets flex-basis:0 so its now-100%-wide sub
   child doesn't inflate the shead's intrinsic width and wrap the home button onto a 3rd
   line; the home button aligns to the title row (flex-start) as the headline is 2 rows.
   Compound/3-class selectors below out-specific the base .wxs-fcpage__head rules. */
@media (max-width: 620px) {
  .wxs-fcpage__head.wxs-fcpage__head--issue { align-items: flex-start; }
  .wxs-fcpage__head--issue .wxs-shead.wxs-shead--page { flex: 1 1 0; }
  /* title stays beside the icon (flex-basis 0 → doesn't break to its own flex line);
     the rule is dropped and tracking tightened so it holds one line on a phone */
  .wxs-fcpage__head--issue .wxs-shead--page .wxs-shead__t { flex: 1 1 0; min-width: 0; letter-spacing: .3px; }
  .wxs-fcpage__head--issue .wxs-shead--page .wxs-shead__rule { display: none; }
  .wxs-fcpage__head--issue .wxs-shead--page .wxs-shead__sub {
    display: block; order: 9; flex-basis: 100%; padding-left: 35px; margin: 2px 0 0; white-space: normal; }
  .wxs-fcpage__head--issue .wxs-shead--page .wxs-shead__sub::before { content: none; }
}
.wxs-ggrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gap); }
/* swipe-hint arrow (mobile only) — positioned on the wrapper, sits over the grid's
   right edge; hidden on desktop where all charts are visible at once */
.wxs-ggrid-wrap { position: relative; }
.wxs-ggrid-hint { display: none; }
/* graph cards: same deal as .wxs-card — translucent fill + sheen, no backdrop blur
   (they're the biggest group, 14 of them, all over the flat page gradient) */
.wxs-gcard {
  background-color: var(--glass-bg);
  background-image: linear-gradient(150deg, rgba(255,255,255,.045), rgba(255,255,255,0) 46%);
  border: 1px solid var(--glass-brd); border-radius: var(--r-md);
  padding: 12px 14px 7px; box-shadow: var(--glass-shadow-lo), var(--inset-hi);
  /* Grid items default to min-width:auto (= min-content). After a portrait→landscape
     flip the ECharts canvas keeps its old (wider, portrait) pixel width, and that
     intrinsic width props the grid track open so `1fr` can't shrink — the 1-hour grid
     (3 columns) then overflows the viewport until a refresh. min-width:0 lets the track
     shrink below the stale canvas so ECharts re-measures and resizes down correctly. */
  min-width: 0;
}
.wxs-gcard__head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 4px; }
.wxs-gcard__title { font-size: 11px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase; color: var(--txt-2); }
.wxs-gcard__val { font-size: 16px; font-weight: 800; color: var(--txt-0); font-variant-numeric: tabular-nums; }
/* 24h cards: value + a small caption clarifying what the figure is (Average / Dominant Dir / …) */
.wxs-gcard__vwrap { display: inline-flex; flex-direction: column; align-items: flex-end; line-height: 1.05; }
.wxs-gcard__lbl { font-size: 8.5px; font-weight: 700; letter-spacing: .4px; text-transform: uppercase; color: var(--txt-3); margin-top: 1px; white-space: nowrap; }
.wxs-gchart { width: 100%; min-width: 0; height: 78px; }
@media (max-width: 900px) { .wxs-ggrid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .wxs-ggrid { grid-template-columns: 1fr; } }

/* 24-hour graphs: 2 columns, taller charts */
.wxs-ggrid--2 { grid-template-columns: repeat(2, 1fr); }
.wxs-gchart--24 { height: 200px; }
@media (max-width: 900px) { .wxs-ggrid--2 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 680px) { .wxs-ggrid--2 { grid-template-columns: 1fr; } }

/* mobile: horizontal swipe through the graphs — ONE full-width column at a time
   (= 2 stacked graphs), so each chart gets the maximum screen width. Scrollbar
   hidden. Placed after the rules above so it wins on phones; desktop untouched. */
@media (max-width: 620px) {
  .wxs-ggrid {
    grid-template-columns: none;
    grid-template-rows: repeat(2, auto);
    grid-auto-flow: column;
    grid-auto-columns: 100%;                 /* one full-width column per view */
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;                    /* Firefox: hide scrollbar */
    -ms-overflow-style: none;                 /* old Edge/IE */
  }
  .wxs-ggrid::-webkit-scrollbar { display: none; }   /* WebKit: hide scrollbar */
  .wxs-gcard { scroll-snap-align: start; }
  .wxs-gchart { height: 108px; }             /* taller now that 1h charts are full-width */
  .wxs-gchart--24 { height: 190px; }
  /* swipe hint: minimal glass chevron nudging right, centred on the grid's right
     edge (in the gap between the two stacked charts). JS hides it at the last view. */
  .wxs-ggrid-hint {
    display: flex; align-items: center; justify-content: center;
    position: absolute; right: 5px; top: 50%; transform: translateY(-50%);
    z-index: 6; width: 30px; height: 30px; margin: 0; padding: 0;
    border-radius: 50%; cursor: pointer; color: #bcd6f5;
    background: rgba(14,22,42,.66); border: 1px solid rgba(120,160,230,.3);
    -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
    box-shadow: 0 3px 10px rgba(0,0,0,.35);
    animation: wxsHintNudge 1.8s ease-in-out infinite;
  }
  .wxs-ggrid-hint svg { display: block; width: 16px; height: 16px; }
  .wxs-ggrid-hint.is-hidden { display: none; }
  /* left-side twin: appears once you've scrolled right, pointing back to earlier graphs */
  .wxs-ggrid-hint--left { right: auto; left: 5px; animation-name: wxsHintNudgeL; }
}
@keyframes wxsHintNudge {
  0%, 100% { transform: translateY(-50%) translateX(0); }
  50%      { transform: translateY(-50%) translateX(3px); }
}
@keyframes wxsHintNudgeL {
  0%, 100% { transform: translateY(-50%) translateX(0); }
  50%      { transform: translateY(-50%) translateX(-3px); }
}
@media (prefers-reduced-motion: reduce) { .wxs-ggrid-hint { animation: none; } }
html.wxs-lite .wxs-ggrid-hint { animation: none; }

/* ================= FORECAST (WXSIM) ================= */
.wxs-forecast { max-width: var(--maxw); margin: 30px auto 0; padding: 0 var(--gutter); }
.wxs-forecast__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 14px; margin-bottom: 14px; flex-wrap: wrap; }
.wxs-fc-btn {
  display: inline-flex; align-items: center; gap: 7px; flex: none;
  font-size: 13px; font-weight: 700; color: var(--txt-0);
  padding: 9px 16px; border-radius: 999px;
  background: var(--accent-soft); border: 1px solid var(--glass-brd-hi); transition: .16s;
}
.wxs-fc-btn:hover { background: rgba(79,144,224,.28); transform: translateY(-1px); }
.wxs-fc-btn svg { width: 16px; height: 16px; }
/* mobile: bring the forecast headline onto the SAME level as the "Full Forecast"
   button (it dropped to a 3rd row before). The trailing rule is dropped for room; the
   title (long in both EL & EN) shrinks and wraps to two lines on the left while the
   compact button stays on one line at the right, vertically centred against it. Unlike
   the graph section subs (hidden on mobile), the forecast KEEPS its issue time/date —
   moved onto its own line just under the title. Header ~100px → ~46px. */
@media (max-width: 620px) {
  .wxs-forecast .wxs-shead { flex-wrap: wrap; align-items: center; column-gap: 10px; row-gap: 4px; margin-bottom: 12px; }
  .wxs-forecast .wxs-shead__rule { display: none; }
  /* flex-basis 0 so the title's natural width doesn't count in line-breaking — keeps
     icon+title+button together on row 1 (title grows into the gap, wraps internally);
     only the 100%-basis sub is forced onto row 2. */
  .wxs-forecast .wxs-shead__t { font-size: 11px; letter-spacing: .4px; line-height: 1.28;
    white-space: normal; flex: 1 1 0; min-width: 0; }
  .wxs-forecast .wxs-fc-btn { flex: none; font-size: 11px; padding: 7px 13px; gap: 5px; white-space: nowrap; }
  .wxs-forecast .wxs-fc-btn svg { width: 14px; height: 14px; }
  /* issue time/date on its own line under the title (order:9 + 100% basis pushes it
     below the icon/title/button row; padding-left aligns it with the title text). The
     leading "·" is only meaningful in the inline desktop form, so drop it here. */
  .wxs-forecast .wxs-shead__sub { order: 9; flex-basis: 100%; padding-left: 35px; margin: 0; white-space: normal; }
  .wxs-forecast .wxs-shead__sub::before { content: none; }
}
/* mobile: drop the descriptive subs on the GRAPH section heads (1h "Εξέλιξη παραμέτρων"
   / 24h "Εξέλιξη τελευταίων 24 ωρών") — the icon + title + rule carry it, cleaner and
   more minimal. Forecast is excluded (it keeps its issue time/date, handled above). */
@media (max-width: 620px) {
  .wxs-graphs .wxs-shead__sub { display: none; }
}

/* ---- dashboard media previews: big camera + stacked satellite/lightning ---- */
.wxs-media { max-width: var(--maxw); margin: 30px auto 0; padding: 0 var(--gutter);
  display: flex; gap: var(--gap); align-items: stretch; }
.wxs-media-box--cam { flex: 2.6 1 0; }
.wxs-media-stack { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: var(--gap); }
.wxs-media-stack .wxs-media-box { flex: 0 0 auto; }
.wxs-media-box { display: flex; flex-direction: column; gap: 9px; min-width: 0; min-height: 0; }
/* the stacked previews (near-square 4/3) set the row height; the wider camera
   fills the same height and the webcam image cover-crops a bit, so all bottoms align */
.wxs-media-stack .wxs-media-frame { aspect-ratio: 4 / 3; flex: none; }
.wxs-media-box--cam .wxs-media-frame { flex: 1 1 auto; aspect-ratio: auto; min-height: 0; }
.wxs-media-box__head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.wxs-media-box__title { font-size: 13px; font-weight: 700; letter-spacing: .2px; color: var(--txt-0); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wxs-media-frame {
  display: block; position: relative; aspect-ratio: 16 / 10; line-height: 0;
  border-radius: var(--r-md); overflow: hidden;
  border: 1px solid var(--glass-brd); background: #0b1322; box-shadow: var(--glass-shadow);
  transition: border-color .2s;
}
.wxs-media-frame:hover { border-color: rgba(120,160,230,.42); }
.wxs-media-img { display: block; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .45s ease, transform .6s ease; }
.wxs-media-img.is-loaded, .sat-stage.wxs-media-img { opacity: 1; }
.wxs-media-frame:hover .wxs-media-img { transform: scale(1.04); }
/* satellite preview: let the borrowed sat-stage fill this frame (cover-crop) */
.wxs-media-frame .sat-stage { position: absolute; inset: 0; width: 100%; height: 100%; aspect-ratio: auto; }
.wxs-media-badge {
  position: absolute; top: 9px; left: 9px; z-index: 2; line-height: 1;
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 9px; border-radius: 999px;
  font-size: 10px; font-weight: 700; letter-spacing: .4px; color: var(--txt-0);
  background: rgba(8,12,24,.6); border: 1px solid var(--glass-brd);
  -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px);
}

/* lightning detector mini-map (basemap + projected strikes, ltradar.js) */
.wxs-ltmap-frame { background: #0a1422; }
.wxs-ltmap__base { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: .9; }
.wxs-ltmap-frame.is-nomap .wxs-ltmap__base { display: none; }
/* 100 km range ring = a circle inscribed in the height (Mercator square px) */
.wxs-ltmap__ring { position: absolute; top: 0; bottom: 0; left: 50%; transform: translateX(-50%); aspect-ratio: 1;
  border-radius: 50%; border: 1px solid rgba(120,200,255,.34); box-shadow: inset 0 0 18px rgba(80,150,230,.12); pointer-events: none; }
.wxs-ltmap__station { position: absolute; left: 50%; top: 50%; width: 7px; height: 7px; transform: translate(-50%, -50%); z-index: 2;
  border-radius: 50%; background: #eafef8; box-shadow: 0 0 0 2px rgba(8,14,26,.85), 0 0 7px rgba(255,255,255,.7); pointer-events: none; }
.wxs-ltmap__strikes { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.wxs-ltmap__strike { position: absolute; width: 7px; height: 7px; transform: translate(-50%, -50%); border-radius: 50%;
  background: #ffcf4a; box-shadow: 0 0 5px rgba(255,205,74,.9); }
.wxs-ltmap__strike.is-close { background: #ff6b5a; box-shadow: 0 0 6px rgba(255,107,90,.95); }
.wxs-ltmap__attr { position: absolute; right: 7px; bottom: 6px; z-index: 2; pointer-events: none;
  font-size: 8.5px; font-weight: 600; color: rgba(190,210,235,.5); text-shadow: 0 1px 2px rgba(0,0,0,.6); }
.wxs-media-badge--lt { color: #ffd98a; }
.wxs-media-badge__u { font-size: .8em; font-weight: 600; opacity: .75; margin-left: 1px; }
.wxs-radar-range { position: absolute; left: 9px; bottom: 8px; z-index: 2; pointer-events: none;
  font-size: 9.5px; font-weight: 700; letter-spacing: .3px; color: rgba(170,210,245,.7); text-shadow: 0 1px 2px rgba(0,0,0,.6); }

/* ---- On-this-day records (smaller, italic to read as historic vs live;
       year each record was set + today's date) ---- */
.wxs-otd .wxs-rows--lg .wxs-kv b { font-size: 13.5px; font-style: italic; }
.wxs-otd-yr { font-size: 10px; font-weight: 700; font-style: italic; color: var(--txt-3); margin-left: 6px; vertical-align: middle; }
.wxs-otd-date { margin-left: auto; font-size: 11px; font-weight: 700; letter-spacing: .3px; color: var(--txt-3); }

/* ---- Lightning Activity (own short mini-card; sits ABOVE On-this-day) ---- */
/* On-this-day grows to fill the gap below the lightning card; its records
   spread to fill so the box doesn't look empty */
/* On-this-day + All-Time paired side-by-side below the lightning card. Each takes
   half the span-4 column, so records render VERTICAL (label over value) with small
   fonts to fit both. */
.wxs-otd-col .wxs-otd-pair { flex: 1; display: flex; gap: var(--gap); min-height: 0; }
.wxs-otd-pair > .wxs-card { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; }
.wxs-otd-pair .wxs-card__title { font-size: 10.5px; }
.wxs-otd-pair .wxs-otd-date { font-size: 9.5px; }
.wxs-otd-pair .wxs-rows--lg { flex: 1; justify-content: space-between; }
.wxs-otd-pair .wxs-kv { flex-direction: column; align-items: flex-start; gap: 1px; min-width: 0; padding-bottom: 5px; }
.wxs-otd-pair .wxs-kv i { font-size: 9.5px; opacity: .85; white-space: nowrap; }
.wxs-otd-pair .wxs-otd .wxs-rows--lg .wxs-kv b { font-size: 13px; font-style: normal; white-space: nowrap; }
.wxs-otd-pair .wxs-otd-yr { margin-left: 4px; }
.wxs-otd-pair .wxs-alltime .wxs-at-cell { display: block; }
.wxs-otd-pair .wxs-alltime .wxs-at-cell b { font-size: 13px; font-weight: 700; white-space: nowrap; }
.wxs-otd-pair .wxs-alltime .wxs-at-cell u { font-size: 9px; font-weight: 600; text-decoration: none; color: var(--txt-3); font-variant-numeric: tabular-nums; margin-left: 4px; white-space: nowrap; }
.wxs-otd-pair .wxs-rec-un { font-size: .68em; font-weight: 600; margin-left: 3px; opacity: .78; }
.wxs-otd-pair .wxs-rec-dir { font-size: .68em; font-weight: 700; margin-left: 4px; opacity: .82; }
.wxs-ltact { flex: 0 0 auto; display: flex; flex-direction: column; gap: 14px; padding: 15px 16px; }
.wxs-ltact__row { display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap; }
.wxs-ltact__bolt { flex: none; font-size: 13px; line-height: 1; color: #ffd24a; }
.wxs-ltact__metric { display: inline-flex; align-items: baseline; gap: 6px; }
.wxs-ltact__lbl { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .3px; color: var(--txt-3); }
.wxs-ltact__num { font-size: 18px; font-weight: 800; line-height: 1; color: #ffd24a; font-variant-numeric: tabular-nums; }
.wxs-ltact__sep { color: var(--txt-3); font-weight: 700; opacity: .55; }
.wxs-ltact__status { display: flex; align-items: center; gap: 8px; padding: 9px 11px; border-radius: 9px;
  font-size: 10.5px; font-weight: 700; line-height: 1.2; }
.wxs-ltact__status[hidden] { display: none; }
.wxs-ltact__status--alert { color: #ffe3b0; background: rgba(255,150,60,.13); border: 1px solid rgba(255,170,80,.34); }
.wxs-ltact__status--ok { color: #b8e6cd; background: rgba(64,196,128,.10); border: 1px solid rgba(74,200,140,.26); }
.wxs-ltact__dot { width: 8px; height: 8px; flex: none; border-radius: 50%; background: #46c882; box-shadow: 0 0 6px rgba(70,200,130,.6); }
.wxs-ltact__pulse { width: 8px; height: 8px; flex: none; border-radius: 50%; background: #ff8a3a; box-shadow: 0 0 0 0 rgba(255,138,58,.6); animation: wxsLtPulse 1.4s ease-out infinite; }
@keyframes wxsLtPulse { 0% { box-shadow: 0 0 0 0 rgba(255,138,58,.6); } 70% { box-shadow: 0 0 0 9px rgba(255,138,58,0); } 100% { box-shadow: 0 0 0 0 rgba(255,138,58,0); } }
@media (max-width: 700px) {
  .wxs-media { flex-direction: column; }
  .wxs-media-stack { flex-direction: column; }
  .wxs-media-box--cam { flex: none; }   /* stop flex-grow:2.6 collapsing it to 0 height in the column */
  .wxs-media-box--cam .wxs-media-frame, .wxs-media-stack .wxs-media-frame { aspect-ratio: 16 / 10; flex: none; }
}

.wxs-fc-days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 10px; }
.fc-day {
  display: flex; flex-direction: column; align-items: center; text-align: center; gap: 5px;
  padding: 14px 8px 12px; border-radius: var(--r-md);
  background: var(--glass-bg-lo); border: 1px solid var(--glass-brd); box-shadow: var(--inset-hi);
}
.fc-day__top { display: flex; flex-direction: column; gap: 1px; }
.fc-day__label { font-size: 12.5px; font-weight: 800; color: var(--txt-0); text-transform: capitalize; }
.fc-day__date { font-size: 10.5px; font-weight: 700; color: var(--txt-3); font-variant-numeric: tabular-nums; }
.fc-day__ico { width: 52px; height: 52px; margin: 2px 0; }
.fc-day__ico .wxi { width: 100%; height: 100%; }
.fc-day__cond { font-size: 11px; font-weight: 700; color: var(--txt-2); line-height: 1.25; min-height: 26px; display: flex; align-items: center; }
.fc-day__temps { display: flex; align-items: baseline; gap: 8px; font-variant-numeric: tabular-nums; }
.fc-hi { font-size: 18px; font-weight: 800; }
.fc-lo { font-size: 14px; font-weight: 600; opacity: .85; }
.fc-day__meta { display: flex; align-items: center; gap: 9px; font-size: 11px; color: var(--txt-2); }
.fc-pop { display: inline-flex; align-items: center; gap: 3px; font-weight: 700; color: var(--accent-2); }
.fc-pop .fc-i { width: 12px; height: 12px; }
.fc-precip { color: var(--accent-2); }   /* mm matches the pop% light-blue for readability */
.fc-day__wind { display: flex; align-items: center; gap: 5px; font-size: 10.5px; font-weight: 700; color: var(--txt-2); margin-top: 1px; }
.fc-wind-ic { display: inline-flex; }
.fc-windarrow { width: 13px; height: 13px; color: var(--accent); }
.fc-wind-txt small { color: var(--txt-3); }

/* ---- detailed day+night cards (forecast sub-page only) ---- */
.fc-day--detail { gap: 8px; padding: 13px 7px 11px; }
.fc-day--detail .fc-day__temps { gap: 7px; }
.fc-halves { display: flex; flex-direction: column; gap: 7px; width: 100%; margin-top: 2px; }
.fc-half {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  width: 100%; padding: 9px 5px; border-radius: 12px; border: 1px solid var(--glass-brd);
}
.fc-half--day   { background: linear-gradient(180deg, rgba(255,191,102,.08), rgba(255,255,255,.015)); }
.fc-half--night { background: linear-gradient(180deg, rgba(123,160,235,.10), rgba(255,255,255,.015)); }
.fc-half__label { font-size: 9.5px; font-weight: 800; letter-spacing: .6px; text-transform: uppercase; }
.fc-half--day   .fc-half__label { color: #ffbf66; }
.fc-half--night .fc-half__label { color: #9bb6ee; }
.fc-half__ico { width: 42px; height: 42px; }
.fc-half__ico .wxi { width: 100%; height: 100%; }
.fc-half__temp { font-size: 17px; font-weight: 800; font-variant-numeric: tabular-nums; line-height: 1; }
.fc-half__cond { font-size: 10px; font-weight: 700; color: var(--txt-2); line-height: 1.2; min-height: 24px; display: flex; align-items: center; text-align: center; }
.fc-half__meta { display: flex; align-items: center; gap: 8px; font-size: 10px; color: var(--txt-2); }
.fc-half__wind { display: flex; align-items: center; gap: 4px; font-size: 9.5px; font-weight: 700; color: var(--txt-2); }
@media (max-width: 1000px) {
  .wxs-fc-days { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: 6px; -webkit-overflow-scrolling: touch; }
  .wxs-fc-days::-webkit-scrollbar { display: none; }
  .fc-day { flex: 0 0 30%; min-width: 124px; scroll-snap-align: start; }
}
@media (max-width: 600px) { .fc-day { flex-basis: 44%; } }
/* Tablets: narrower day cards so more of the week is visible at a glance (~4.7 days
   instead of ~3.2). Bounded to the range where the carousel actually exists (the grid
   takes over above 1000), so phones (≤620) keep their 44% cards and desktop is
   untouched. The 124px min-width above still guards the narrowest tablets. */
@media (min-width: 621px) and (max-width: 1000px) { .fc-day { flex-basis: 20%; } }

/* ---- forecast sub-page (wxsimforecast) ---- */
.wxs-fcpage__head { display: flex; align-items: center; gap: 16px; margin: 6px 0 20px; }
.wxs-back { display: inline-flex; align-items: center; flex: none; font-size: 13px; font-weight: 700; color: var(--txt-2);
  padding: 8px 14px; border-radius: 999px; background: var(--glass-bg-lo); border: 1px solid var(--glass-brd); }
.wxs-back:hover { color: var(--txt-0); border-color: var(--glass-brd-hi); }
.wxs-fcpage__title { font-size: clamp(20px, 2.6vw, 28px); font-weight: 800; color: var(--txt-0); margin: 0; letter-spacing: -.3px; }
.wxs-fcpage__titles .wxs-graphs__sub { font-size: 12.5px; }
/* Desktop: put the subpage title + subtitle on ONE line, ·-joined (there's room). Mobile
   (≤620) reverts to the stacked layout and swaps the back button for a home icon. Shared
   by all subpages (they all use .wxs-fcpage__head > .wxs-back + .wxs-fcpage__titles). */
.wxs-fcpage__titles { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 0; }
.wxs-fcpage__titles .wxs-graphs__sub::before { content: "·"; margin: 0 .5em; color: var(--txt-2); }
@media (max-width: 620px) {
  .wxs-fcpage__titles { display: block; }
  .wxs-fcpage__titles .wxs-graphs__sub::before { content: none; }
  /* back button → compact circular home icon (frees space; text hidden via font-size:0) */
  .wxs-fcpage__head .wxs-back { width: 36px; height: 36px; padding: 0; justify-content: center; font-size: 0; }
  .wxs-fcpage__head .wxs-back::before {
    content: ""; width: 17px; height: 17px; background-color: currentColor;
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='%23000' d='M12 3 3 10v11h6v-6h6v6h6V10z'/></svg>") center / contain no-repeat;
            mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='%23000' d='M12 3 3 10v11h6v-6h6v6h6V10z'/></svg>") center / contain no-repeat;
  }
}

/* ================= GRAPHS PAGE (wxgraphs.php) ================= */
.wxs-gp-ivs {
  display: inline-flex; gap: 4px; margin-left: auto; flex: none; padding: 4px;
  border-radius: 12px; background: var(--glass-bg-lo); border: 1px solid var(--glass-brd);
}
.wxs-gp-iv {
  font: inherit; font-size: 12.5px; font-weight: 700; color: var(--txt-2); cursor: pointer;
  padding: 7px 14px; border-radius: 9px; background: transparent; border: 0; white-space: nowrap;
  transition: color .15s, background .15s;
}
.wxs-gp-iv:hover { color: var(--txt-0); }
.wxs-gp-iv.is-on { color: var(--txt-0); background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--glass-brd-hi); }
.wxs-gp-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gap); }
.wxs-gp-grid[hidden] { display: none; }   /* class display: grid otherwise beats [hidden] */
.wxs-gp-card {
  border-radius: var(--r-md); padding: 14px 16px 10px;
  /* solid (de-glassed) fill instead of the translucent --glass-bg-lo: the charts
     read cleaner on an opaque panel, and it's lighter to composite / less "glassy" */
  background: #141e39; border: 1px solid var(--glass-brd); box-shadow: var(--inset-hi);
}
.wxs-gp-cardhd { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.wxs-gp-title { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--txt-2); }
.wxs-gp-kind { margin-left: auto; font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--txt-3); }
.wxs-gp-val { font-size: 17px; font-weight: 800; font-variant-numeric: tabular-nums; }
.wxs-gp-chart { width: 100%; height: 205px; }
/* each card expands into the big single-parameter view */
.wxs-gp-card.is-expandable { cursor: pointer; transition: border-color .15s, background .15s, transform .15s; }
.wxs-gp-card.is-expandable:hover { border-color: var(--glass-brd-hi); background: #1b2649; }
.wxs-gp-card.is-expandable:hover .wxs-gp-expand { color: var(--txt-1); }
.wxs-gp-expand { display: inline-flex; flex: none; width: 15px; height: 15px; color: var(--txt-3); transition: color .15s; }
.wxs-gp-expand svg { width: 100%; height: 100%; }

/* single-parameter focus view */
.wxs-gp-focus[hidden] { display: none; }
.wxs-gp-focushd { display: flex; align-items: center; gap: 14px; margin-bottom: 12px; }
.wxs-gp-focustitle { font-size: 16px; font-weight: 800; text-transform: uppercase; letter-spacing: .5px; color: var(--txt-0); }
.wxs-gp-focusval { font-size: 22px; }
.wxs-gp-focuschart {
  width: 100%; height: 560px; padding: 14px 12px 8px; border-radius: var(--r-md);
  background: #141e39; border: 1px solid var(--glass-brd); box-shadow: var(--inset-hi);
}
.wxs-gp-zoomhint { margin: 10px 0 0; text-align: center; font-size: 11.5px; color: var(--txt-3); }
@media (max-width: 760px) {
  .wxs-gp-grid { grid-template-columns: 1fr; }
  .wxs-gp-chart { height: 185px; }
  .wxs-fcpage__head { flex-wrap: wrap; }
  .wxs-gp-ivs { margin-left: 0; width: 100%; justify-content: center; }
  .wxs-gp-focuschart { height: 440px; }
}
.wxs-fcpage__cards { margin: 0; padding: 0; max-width: none; }
.wxs-fc-sec { margin-top: 26px; }
.wxs-fc-sec .wxs-graphs__title { margin-bottom: 12px; }
.wxs-fc-meteo { position: relative; padding: 10px 8px 6px; border-radius: var(--r-lg);
  background-color: var(--glass-bg); background-image: linear-gradient(150deg, rgba(255,255,255,.05), rgba(255,255,255,0) 46%);
  border: 1px solid var(--glass-brd); box-shadow: var(--glass-shadow-lo), var(--inset-hi); }
.wxs-fc-chart-wrap { width: 100%; }
.wxs-fc-chart { width: 100%; height: 440px; }
.wxs-fc-text { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px 18px; }
.wxs-fct { padding: 12px 16px; border-radius: var(--r-md); background: var(--glass-bg-lo); border: 1px solid var(--glass-brd); }
.wxs-fct--full { grid-column: 1 / -1; }
.wxs-fct__name { display: block; font-size: 13px; font-weight: 800; color: var(--accent-2); margin-bottom: 4px; text-transform: capitalize; }
.wxs-fct__txt { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--txt-1); }
.wxs-fc-disclaimer { margin: 14px 2px 0; font-size: 12px; font-style: italic; color: var(--txt-3); }
.wxs-fc-disclaimer:empty { display: none; }
@media (max-width: 700px) {
  .wxs-fc-text { grid-template-columns: 1fr; }
  /* meteogram: keep it WIDE (each day gets room) and scroll horizontally instead of
     cramming a whole week into one screen width */
  .wxs-fc-chart-wrap { overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; }
  .wxs-fc-chart { width: 680px; height: 360px; }
  /* soft right-edge cue that there's more of the week to swipe to */
  .wxs-fc-meteo::after { content: ""; position: absolute; top: 10px; right: 6px; bottom: 6px; width: 26px;
    background: linear-gradient(to right, rgba(11,18,34,0), var(--glass-bg)); pointer-events: none; }
}

/* ---- hourly forecast table (WXSIM 1-hour detail) — day-tabbed. Ported from the clone
   stations so the shared forecast.js renderHourlyTable styles correctly on Dexameni. ---- */
.wxs-fc-hourly { padding: 0; border-radius: var(--r-lg); overflow: hidden; }
.wxs-fh-tabs { display: flex; gap: 4px; overflow-x: auto; padding: 8px 8px 0; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.wxs-fh-tabs::-webkit-scrollbar { display: none; }
.wxs-fh-tab { flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 1px; min-width: 60px;
  padding: 7px 13px; border: 1px solid var(--glass-brd); border-bottom: 0; border-radius: 11px 11px 0 0;
  background: var(--glass-bg-lo); color: var(--txt-2); font: inherit; cursor: pointer; transition: .15s; white-space: nowrap; }
.wxs-fh-tab:hover { color: var(--txt-0); border-color: var(--glass-brd-hi); }
.wxs-fh-tab b { font-size: 12.5px; font-weight: 700; }
.wxs-fh-tab small { font-size: 10.5px; color: var(--txt-3); font-variant-numeric: tabular-nums; }
.wxs-fh-tab.is-on { background: var(--accent-soft); border-color: var(--glass-brd-hi); color: var(--txt-0); }
.wxs-fh-tab.is-on b { color: var(--accent-2); }
.wxs-fh-wrap { overflow-x: auto; border-top: 1px solid var(--glass-brd); }
.wxs-fh { width: 100%; border-collapse: collapse; font-size: 13px; }
.wxs-fh thead th { position: sticky; top: 0; z-index: 3; background: rgba(16,24,44,.97);
  color: var(--txt-2); font-weight: 700; font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase;
  text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--glass-brd); white-space: nowrap; }
.wxs-fh tbody td { padding: 6px 12px; border-bottom: 1px solid rgba(120,150,200,.08); white-space: nowrap; }
.wxs-fh tbody tr:hover td { background: rgba(120,160,230,.05); }
.wxs-fh__day td { background: rgba(22,32,58,.92); color: var(--txt-0); font-weight: 800; font-size: 12px; padding: 7px 12px; }
.wxs-fh__h { font-variant-numeric: tabular-nums; color: var(--txt-2); font-weight: 600; }
.wxs-fh__ic { display: inline-flex; width: 30px; height: 30px; vertical-align: middle; margin-right: 9px; }
.wxs-fh__ic svg { width: 30px; height: 30px; }
.wxs-fh__t { font-weight: 800; font-variant-numeric: tabular-nums; }
.wxs-fh__wi { display: inline-flex; vertical-align: middle; color: var(--accent-2); margin-right: 3px; }
.wxs-fh__wi svg { width: 13px; height: 13px; }
.wxs-fh__wt { font-variant-numeric: tabular-nums; color: var(--txt-1); }
.wxs-fh__wt small { color: var(--txt-3); }
.wxs-fh__mm { color: var(--accent-2); }
.wxs-fh__pp { color: var(--txt-2); font-variant-numeric: tabular-nums; }
.wxs-fh__s, .wxs-fh__cl { font-variant-numeric: tabular-nums; color: var(--txt-1); }
:root[data-theme="light"] .wxs-fh thead th { background: rgba(232,240,252,.97); }
:root[data-theme="light"] .wxs-fh__day td { background: rgba(214,226,244,.94); }

/* ================= STORM TRACKER (Boltek) ================= */
/* map (left) + glass info boxes (right) */
.wxs-storm-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) 264px; gap: 14px;
  max-width: 1180px; margin: 0 auto; align-items: stretch;
}
.wxs-storm-mapcard {
  position: relative; border-radius: var(--r-lg); overflow: hidden;
  border: 1px solid var(--glass-brd); box-shadow: var(--glass-shadow), var(--inset-hi);
}
/* map fills the card, which stretches to match the info column's height.
   Round the map root AND the WebGL canvas itself: Firefox won't clip an
   absolutely-positioned, GPU-composited <canvas> to an ancestor's rounded
   overflow:hidden (the card), so its square corners bled past the radius in
   FF only. Rounding the canvas directly clips it in every browser. */
.wxs-storm-map { width: 100%; height: 100%; min-height: 480px; border-radius: var(--r-lg); }
.wxs-storm-map .maplibregl-canvas { border-radius: var(--r-lg); }
.maplibregl-map { font-family: var(--font); }
.wxs-sm-station {
  width: 13px; height: 13px; border-radius: 50%; background: #46d18a; border: 2px solid #0a1018;
  box-shadow: 0 0 0 3px rgba(70,209,138,.28), 0 0 11px rgba(70,209,138,.6);
}
.wxs-sm-storm { display: flex; flex-direction: column; align-items: center; pointer-events: none; }
.wxs-sm-diamond { width: 24px; height: 24px; transform: rotate(45deg); border: 2.5px solid #7ee0a6; }
/* diamond colour by intensity (pastel): weak/mod/strong/severe — TRAC class word,
   else peak-rate; shared with the storm tables (see WXS.stormLevel) */
.wxs-sm-diamond--weak   { border-color: #7ee0a6; background: rgba(126,224,166,.14); box-shadow: 0 0 11px rgba(126,224,166,.5); }
.wxs-sm-diamond--mod    { border-color: #ffe07a; background: rgba(255,224,122,.15); box-shadow: 0 0 11px rgba(255,224,122,.5); }
.wxs-sm-diamond--strong { border-color: #ffb060; background: rgba(255,176,96,.16); box-shadow: 0 0 12px rgba(255,176,96,.55); }
.wxs-sm-diamond--severe { border-color: #ff8f8f; background: rgba(255,143,143,.18); box-shadow: 0 0 14px rgba(255,143,143,.62); }
.wxs-sm-label {
  margin-top: 4px; font-size: 11px; font-weight: 800; color: #eaf1fb;
  background: rgba(10,18,30,.62); padding: 1px 6px; border-radius: 5px; text-shadow: 0 1px 2px #000;
}
/* bottom-left stack: data-source credit pill ABOVE the legend */
.wxs-sm-bl { position: absolute; left: 10px; bottom: 10px; z-index: 5; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.wxs-sm-powered {
  font-size: 10.5px; color: var(--txt-2); padding: 4px 9px; border-radius: 999px;
  background: rgba(12,20,38,.9); border: 1px solid var(--glass-brd);
}
.wxs-sm-powered b { font-weight: 700; }
.wxs-sm-powered .pw-link { text-decoration: none; }
.wxs-sm-powered .pw-link:hover b { text-decoration: underline; }
.wxs-sm-powered .pw-boltek { color: #5fd0ff; }
.wxs-sm-powered .pw-nex { color: #ff5454; }
.wxs-sm-powered .pw-storm { color: #aab6c8; }
.wxs-sm-legend {
  display: flex; flex-direction: column; gap: 4px; padding: 6px 9px; border-radius: var(--r-md);
  background: rgba(12,20,38,.9); border: 1px solid var(--glass-brd);
  font-size: 9.5px; color: var(--txt-1);
}
.wxs-sm-leg-toggle {
  display: flex; align-items: center; gap: 6px; padding: 0; background: none; border: none;
  cursor: pointer; color: var(--txt-2); font: inherit; font-size: 9px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .5px;
}
.wxs-sm-leg-cv { display: inline-block; font-size: 8px; transition: transform .2s ease; }
.wxs-sm-legend.is-collapsed { gap: 0; }
.wxs-sm-legend.is-collapsed .wxs-sm-leg-cv { transform: rotate(-90deg); }
.wxs-sm-legend.is-collapsed .wxs-sm-leg-body { display: none; }
.wxs-sm-leg-body { display: flex; flex-direction: column; gap: 4px; }
.wxs-sm-leg-sec { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.wxs-sm-leg-h { font-size: 8.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--txt-2); min-width: 56px; }
.wxs-sm-leg-i { display: inline-flex; align-items: center; gap: 3px; }
.wxs-sm-leg-i svg { width: 12px; height: 12px; }
.wxs-sm-leg-a { display: inline-flex; align-items: center; gap: 3px; color: var(--txt-2); font-variant-numeric: tabular-nums; }
.wxs-sm-leg-a i { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.wxs-sm-leg-a i.wxs-leg-dia { border-radius: 1px; transform: rotate(45deg); }   /* diamond swatch for the intensity legend */
@media (max-width: 600px) { .wxs-sm-bl { left: 8px; bottom: 8px; } .wxs-sm-leg-h { min-width: 0; } }

/* zoom-level control pill (upper-left): Automatic + fixed 1000…100 km */
.wxs-zoom-ctrl {
  position: absolute; left: 10px; top: 10px; z-index: 6;
  font: inherit; font-size: 11px; font-weight: 600; color: var(--txt-1);
  padding: 5px 26px 5px 10px; border-radius: 999px; cursor: pointer; appearance: none; -webkit-appearance: none;
  background: rgba(12,20,38,.92) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 10 10'><path d='M2 3.5l3 3 3-3' stroke='%238fa0bb' stroke-width='1.4' fill='none' stroke-linecap='round'/></svg>") no-repeat right 9px center;
  border: 1px solid var(--glass-brd);
}
.wxs-zoom-ctrl:hover { border-color: rgba(120,160,230,.4); }
.wxs-zoom-ctrl:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(70,209,138,.35); }
.wxs-zoom-ctrl option { background: #0c1426; color: var(--txt-1); }

/* fullscreen-map toggle (MOBILE only — shown via the ≤620 block) */
.wxs-map-fs-btn {
  position: absolute; right: 10px; top: 10px; z-index: 6; display: none;
  width: 34px; height: 34px; align-items: center; justify-content: center; padding: 0;
  border-radius: 10px; cursor: pointer; color: var(--txt-1);
  background: rgba(12,20,38,.92); border: 1px solid var(--glass-brd);
}
.wxs-map-fs-ic { width: 18px; height: 18px; }
.wxs-map-fs-ic--close { display: none; }
body.wxs-smap-fs .wxs-map-fs-ic--open { display: none; }
body.wxs-smap-fs .wxs-map-fs-ic--close { display: block; }

/* strike pulse: a lightweight radar-style "ping" on each new strike — a bright
   type-coloured core that pops + a ring that expands outward. Both animate ONLY
   on pseudo-elements (transform/opacity → GPU compositor), leaving the marker
   element's own transform to MapLibre for positioning. Colour rides currentColor;
   centered via left/top 0 + negative-half margin so the transform is pure scale.
   Self-removing (see flashStrike in stormmap.js). */
.wxs-sm-flash { width: 0; height: 0; color: #fff; pointer-events: none; }
.wxs-flash-ncg { color: #5fd0ff; }
.wxs-flash-pcg { color: #cf90f2; }
.wxs-flash-nic { color: #7fe6a0; }
.wxs-flash-pic { color: #ffe17a; }
.wxs-sm-flash::before,
.wxs-sm-flash::after {
  content: ""; position: absolute; left: 0; top: 0; border-radius: 50%;
  will-change: transform, opacity;
}
/* core: a glowing filled dot that pops in then fades */
.wxs-sm-flash::before {
  width: 10px; height: 10px; margin: -5px 0 0 -5px; background: currentColor;
  box-shadow: 0 0 8px currentColor, 0 0 16px currentColor;
  animation: wxsPingCore .9s ease-out forwards;
}
/* ring: a hollow circle that expands outward and fades */
.wxs-sm-flash::after {
  width: 14px; height: 14px; margin: -7px 0 0 -7px; border: 2.5px solid currentColor;
  animation: wxsPingRing .9s ease-out forwards;
}
@keyframes wxsPingCore {
  0%   { transform: scale(.2);  opacity: 0; }
  20%  { transform: scale(1.1); opacity: 1; }
  100% { transform: scale(.8);  opacity: 0; }
}
@keyframes wxsPingRing {
  0%   { transform: scale(.5);  opacity: .9; }
  100% { transform: scale(3.6); opacity: 0; }
}
/* reduced motion: keep a brief static fade (still signals a new strike), no scaling */
@media (prefers-reduced-motion: reduce) {
  .wxs-sm-flash::after { display: none; }
  .wxs-sm-flash::before { animation: wxsPingCoreRM .9s ease-out forwards; }
}
@keyframes wxsPingCoreRM { 0% { opacity: 1; } 100% { opacity: 0; } }

/* ---- side panel : glass info boxes ---- */
.wxs-storm-side { display: flex; flex-direction: column; gap: 12px; }
/* last-update strip (flashes when a fresh NSRealtime feed arrives) */
.wxs-update { display: flex; align-items: center; gap: 8px; padding: 9px 14px; font-size: 12px; color: var(--txt-2); }
.wxs-update b { margin-left: auto; color: var(--txt-1); font-weight: 700; font-variant-numeric: tabular-nums; }
.wxs-update-dot { width: 8px; height: 8px; border-radius: 50%; background: #46d18a; box-shadow: 0 0 6px rgba(70,209,138,.55); transition: background .3s, box-shadow .3s; }
.wxs-update.is-stale .wxs-update-dot { background: #ff5454; box-shadow: 0 0 7px rgba(255,84,84,.7); }
/* a fresh detector feed gives a SHORT flash on just the LED + the time —
   the box itself stays calm (no full-box background pulse) */
.wxs-update.wxs-updflash .wxs-update-dot { animation: wxsDotFlash .55s ease-out; }
.wxs-update.wxs-updflash b { animation: wxsTimeFlash .55s ease-out; }
@keyframes wxsDotFlash { 0% { transform: scale(1.9); box-shadow: 0 0 11px 3px rgba(70,209,138,.85); } 100% { transform: scale(1); } }
@keyframes wxsTimeFlash { 0% { color: #5ee8a4; text-shadow: 0 0 9px rgba(70,209,138,.75); } 100% { color: var(--txt-1); text-shadow: none; } }
.wxs-sbox {
  border-radius: var(--r-md); padding: 12px 14px;
  background-color: var(--glass-bg); background-image: linear-gradient(150deg, rgba(255,255,255,.05), rgba(255,255,255,0) 46%);
  border: 1px solid var(--glass-brd); box-shadow: var(--glass-shadow-lo), var(--inset-hi);
}
.wxs-sbox-h {
  margin: 0 0 9px; font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .5px; color: var(--txt-2);
}
/* Box 1 — twin counters */
.wxs-sbox--ctr { display: flex; gap: 10px; text-align: center; }
.wxs-ctr { flex: 1; display: flex; flex-direction: column; gap: 2px; padding: 4px 2px; }
.wxs-ctr-n { font-size: 30px; font-weight: 800; line-height: 1; color: #ffd24a; font-variant-numeric: tabular-nums; }
.wxs-ctr-close { color: #ff7a5f; }
.wxs-ctr label { font-size: 10.5px; color: var(--txt-2); }
/* Box 2 & 3 — key/value rows (SCOPED to .wxs-sbox so these don't leak onto the
   dashboard's own .wxs-kv — that generic leak was overriding dashboard colours,
   borders and the Storm-Rain accent) */
.wxs-sbox .wxs-kv { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; padding: 3.5px 0; font-size: 13px; }
.wxs-sbox .wxs-kv + .wxs-kv { border-top: 1px solid rgba(150,180,230,.08); }
.wxs-sbox .wxs-kv i { color: var(--txt-2); font-style: normal; }
.wxs-sbox .wxs-kv b { font-weight: 700; color: var(--txt-1); font-variant-numeric: tabular-nums; text-align: right; }
/* Box 3 — mini 1-hour graph */
.wxs-lt-graph { width: 100%; height: 86px; margin-top: 8px; }
/* Box 4 — distribution bars */
.wxs-dist-row { display: grid; grid-template-columns: 1fr 40px 26px; align-items: center; gap: 6px; padding: 3px 0; font-size: 11px; white-space: nowrap; }
.wxs-dist-cat { display: inline-flex; align-items: center; gap: 5px; min-width: 0; }
.wxs-dist-ic { width: 13px; height: 13px; flex: none; }
.wxs-dist-row i { color: var(--txt-2); font-style: normal; overflow: hidden; text-overflow: ellipsis; }
.wxs-dist-track { height: 7px; border-radius: 4px; background: rgba(150,180,230,.12); overflow: hidden; }
.wxs-dist-track b { display: block; height: 100%; width: 2%; border-radius: 4px; transition: width .5s ease; }
.wxs-dist-row u { text-decoration: none; text-align: right; color: var(--txt-1); font-weight: 700; font-variant-numeric: tabular-nums; }
/* Box 5 — two iOS-style mode switches on one line */
.wxs-sbox--modes { display: flex; gap: 12px; }
.wxs-modecell { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 9px; text-align: center; }
.wxs-modecell-l { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--txt-2); line-height: 1.2; }
.wxs-mode-ic { width: 13px; height: 13px; flex: none; }
.wxs-mode-ic--blitz { color: #ff9e2a; }   /* orange strike */
.wxs-mode-ic--eum { color: #cf90f2; }      /* purple strike */
.wxs-mode-ic--radar { color: #5fc4f0; }    /* blue raindrop */
.wxs-switch { position: relative; display: inline-block; width: 46px; height: 26px; cursor: pointer; flex: none; }
.wxs-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.wxs-switch-track {
  position: absolute; inset: 0; border-radius: 999px;
  background: rgba(150,180,230,.18); border: 1px solid var(--glass-brd);
  transition: background .25s ease;
}
.wxs-switch-track::before {
  content: ""; position: absolute; left: 3px; top: 50%; transform: translateY(-50%);
  width: 20px; height: 20px; border-radius: 50%; background: #f4f8ff;
  box-shadow: 0 1px 3px rgba(0,0,0,.45); transition: transform .25s ease;
}
.wxs-switch input:checked + .wxs-switch-track { background: #46d18a; }
.wxs-switch input:checked + .wxs-switch-track::before { transform: translate(20px, -50%); }
.wxs-switch input:focus-visible + .wxs-switch-track { box-shadow: 0 0 0 3px rgba(70,209,138,.35); }

/* The old ≤880 "map on top + 2-up boxes" tablet layout and its ≤520 companion were
   removed: the ≤1024 reorg block below now owns the whole ≤1024 range (they were fully
   shadowed by it). Desktop (≥1025) keeps the base map + 264px side-column layout. */

/* ---- storm tracker MOBILE + TABLET reorg (≤1024) — desktop (≥1025) untouched:
   update time ABOVE the map · data cards paired 2-up · shrunken map overlays.
   Extended from ≤620 to ≤1024 so ALL portrait tablets — incl. the 13" iPad Pro/Air
   (1024px portrait) — borrow the mobile layout. The 3 JS matchMedia hooks in
   wxstormtracker.php (legend default / fullscreen exit / counter-reparent) use the same
   1024 cutoff. Phones (≤620) are a subset, so their rules are unchanged. ---- */
@media (max-width: 1024px) {
  .wxs-storm-grid { grid-template-columns: 1fr 1fr; gap: 10px; align-items: stretch; }
  .wxs-storm-side { display: contents; }                       /* flatten into the grid */
  .wxs-storm-side .wxs-sbox { grid-column: span 1; }           /* half-width → 2 per row */
  .wxs-storm-side .wxs-update { grid-column: 1 / -1; order: -1; padding: 8px 12px; }  /* update first, above map */
  .wxs-storm-mapcard { grid-column: 1 / -1; }
  /* rate/min counters ride on the map (rule below). Order: modes pill just under the
     map, then last | distribution (equal-height pair), then stats full-width — no gaps */
  .wxs-storm-side .wxs-sbox--modes { grid-column: 1 / -1; order: 1; }
  .wxs-storm-side .wxs-sbox--last  { order: 2; }
  .wxs-storm-side .wxs-sbox--dist  { order: 3; }
  .wxs-storm-side .wxs-sbox--stats { grid-column: 1 / -1; order: 4; }
  .wxs-storm-map { min-height: 520px; }   /* taller portrait map on mobile (needn't be square) */

  /* modes → compact one-line pill directly below the map (non-FS only; FS keeps its own
     bottom-right stacked card via the higher-specificity body.wxs-smap-fs rules) */
  /* compact enough that all 3 toggles fit one line on typical phones (flex-wrap stays
     as a safety net for very narrow ≤~340px screens) */
  body:not(.wxs-smap-fs) .wxs-sbox--modes {
    flex-direction: row; align-items: center; justify-content: center;
    flex-wrap: wrap; gap: 7px 6px; padding: 7px 6px; border-radius: 22px;
  }
  body:not(.wxs-smap-fs) .wxs-sbox--modes .wxs-modecell { flex: 0 1 auto; flex-direction: row; align-items: center; gap: 3px; text-align: left; }
  body:not(.wxs-smap-fs) .wxs-sbox--modes .wxs-mode-ic { width: 11px; height: 11px; }
  body:not(.wxs-smap-fs) .wxs-sbox--modes .wxs-modecell-l { font-size: 8.5px; letter-spacing: .2px; }
  body:not(.wxs-smap-fs) .wxs-sbox--modes .wxs-switch { width: 34.5px; height: 19.5px; }
  body:not(.wxs-smap-fs) .wxs-sbox--modes .wxs-switch-track::before { width: 15px; height: 15px; }
  body:not(.wxs-smap-fs) .wxs-sbox--modes .wxs-switch input:checked + .wxs-switch-track::before { transform: translate(13.5px, -50%); }

  /* shrink map overlays so they stop covering the map */
  /* bottom-left stack reads bottom→top: (FS only) update time · powered · legend. JS keeps
     the update box as the first child; column-reverse flips it to the bottom. Applies to
     non-FS too (just powered · legend) so both modes read legend-on-top consistently. */
  .wxs-sm-bl { gap: 4px; left: 7px; bottom: 7px; flex-direction: column-reverse; }
  .wxs-sm-powered { font-size: 7.5px; padding: 2px 6px; }
  .wxs-sm-legend { font-size: 7px; padding: 3px 6px; gap: 2px; }
  .wxs-sm-leg-toggle { font-size: 7px; gap: 3px; }
  .wxs-sm-leg-cv { font-size: 7px; }
  .wxs-sm-leg-sec { gap: 4px; }
  .wxs-sm-leg-i { gap: 2px; }
  .wxs-sm-leg-i svg { width: 8px; height: 8px; }
  .wxs-sm-leg-a i { width: 5px; height: 5px; }
  .wxs-zoom-ctrl { font-size: 9.5px; padding: 4px 21px 4px 8px; top: 44px; }   /* tucks below the rate pill */

  /* Blitz/EUMETSAT reference pills → bottom-right (off the top-right FS button; the
     bottom offset clears MapLibre's ⓘ attribution). FS raises them above the toggles.
     (.wxs-storm-mapcard prefix outranks the base rule, which is later in the file.) */
  .wxs-storm-mapcard .wxs-map-credits { top: auto; bottom: 42px; }
  .wxs-storm-mapcard .wxs-credit-pill { font-size: 8.5px; padding: 3px 8px; }

  /* compact the paired cards */
  .wxs-sbox { padding: 10px 11px; }
  .wxs-ctr-n { font-size: 22px; }
  .wxs-ctr label { font-size: 9px; }
  .wxs-sbox-h { font-size: 11px; margin-bottom: 8px; }
  .wxs-sbox .wxs-kv { font-size: 10.5px; padding: 2.5px 0; }
  /* distribution: let the long CG/CC labels wrap instead of overflowing at half-width */
  .wxs-dist-row { grid-template-columns: 1fr 28px 22px; gap: 4px; font-size: 8.5px; white-space: normal; }

  /* ---- FULLSCREEN MAP MODE (mobile only) ---- */
  .wxs-map-fs-btn { display: flex; }
  body.wxs-smap-fs { overflow: hidden; }
  body.wxs-smap-fs .wxs-storm-mapcard { position: fixed; inset: 0; z-index: 9000; margin: 0; max-width: none; border: 0; border-radius: 0; }
  body.wxs-smap-fs .wxs-storm-map { height: 100%; min-height: 0; }
  body.wxs-smap-fs .wxs-storm-map,
  body.wxs-smap-fs .wxs-storm-map .maplibregl-canvas { border-radius: 0; }
  body.wxs-smap-fs .wxs-map-fs-btn, body.wxs-smap-fs .wxs-zoom-ctrl, body.wxs-smap-fs .wxs-sm-bl { z-index: 9003; }
  /* overlays: rate/min pill (top-left, zoom below it) · bottom-left stack, bottom→top:
     update time · powered · legend · the 2 mode switches (bottom-right) with the Blitz/
     EUMETSAT reference pills just above them. Last strike + stats + distribution stay
     behind the fixed map. */
  body.wxs-smap-fs .wxs-sbox--last { display: none; }
  /* (bottom-left stack order handled by the shared mobile .wxs-sm-bl column-reverse above) */
  /* reference pills → bottom-right, just above the mode toggles */
  body.wxs-smap-fs .wxs-map-credits { bottom: 108px; z-index: 9002; }
  /* update time → a one-line pill in the bottom-left stack, ABOVE the powered pill
     (JS moves #wxs-lt-updbox into .wxs-sm-bl on enter, restores it on exit) */
  body.wxs-smap-fs .wxs-update {
    width: auto; padding: 3px 10px; border-radius: 999px; font-size: 9px; gap: 6px;
    white-space: nowrap; background-color: rgba(11, 18, 34, 0.9);
  }
  body.wxs-smap-fs .wxs-update b { margin-left: 4px; }
  /* current rate/min → one-line pill overlaid top-center of the map. JS reparents the
     .wxs-sbox--ctr box into the map card on mobile; this styles it for BOTH non-FS
     (absolute over the in-flow map) and FS (absolute over the fixed full-screen map). */
  .wxs-storm-mapcard > .wxs-sbox--ctr {
    /* upper-left corner; the zoom control tucks in just below it (see .wxs-zoom-ctrl),
       giving the pill the full map width to grow into. Only the fullscreen btn shares
       this row (top-right), so max-width reserves room for it. */
    position: absolute; top: 10px; left: 10px;
    z-index: 5; pointer-events: none; white-space: nowrap;
    /* size to content (never clip the 2nd counter); fonts below scale on tiny screens */
    width: max-content; max-width: calc(100% - 56px); padding: 5px 16px; gap: clamp(9px, 3.4vw, 15px);
    border-radius: 999px; align-items: center; background-color: rgba(11, 18, 34, 0.9);
  }
  .wxs-storm-mapcard > .wxs-sbox--ctr .wxs-ctr { flex: none; flex-direction: row; align-items: baseline; gap: 6px; padding: 0; }
  .wxs-storm-mapcard > .wxs-sbox--ctr .wxs-ctr-n { font-size: clamp(14px, 4.4vw, 16.5px); }
  .wxs-storm-mapcard > .wxs-sbox--ctr .wxs-ctr label { font-size: clamp(8px, 2.5vw, 9px); }
  /* FS: keep the pill upper-left just below the notch and above the other overlays; the
     zoom control + fullscreen button take the same safe-area offset so the top-left stack
     (pill over zoom) and the top-right button line up correctly on notched phones */
  body.wxs-smap-fs .wxs-storm-mapcard > .wxs-sbox--ctr { top: calc(env(safe-area-inset-top, 0px) + 10px); z-index: 9002; }
  body.wxs-smap-fs .wxs-zoom-ctrl { top: calc(env(safe-area-inset-top, 0px) + 44px); }
  body.wxs-smap-fs .wxs-map-fs-btn { top: calc(env(safe-area-inset-top, 0px) + 10px); }
  /* mode switches → compact stacked card, bottom-right */
  body.wxs-smap-fs .wxs-sbox--modes {
    position: fixed; right: 10px; bottom: 12px; z-index: 9002;
    flex-direction: column; gap: 5px; width: auto; padding: 6px 9px; background-color: rgba(11, 18, 34, 0.9);
  }
  body.wxs-smap-fs .wxs-sbox--modes .wxs-modecell { flex: none; flex-direction: row; align-items: center; gap: 7px; text-align: left; }
  body.wxs-smap-fs .wxs-sbox--modes .wxs-modecell-l { font-size: 8.5px; flex: 1; }
  body.wxs-smap-fs .wxs-sbox--modes .wxs-mode-ic { width: 11px; height: 11px; }
  body.wxs-smap-fs .wxs-sbox--modes .wxs-switch { width: 36px; height: 20px; }
  body.wxs-smap-fs .wxs-sbox--modes .wxs-switch-track::before { width: 14px; height: 14px; }
  body.wxs-smap-fs .wxs-sbox--modes .wxs-switch input:checked + .wxs-switch-track::before { transform: translate(16px, -50%); }
}

/* ---- tables + 20h graph (below the map) ---- */
.wxs-storm-extra { max-width: 1180px; margin: 18px auto 0; display: flex; flex-direction: column; gap: 16px; }
.wxs-stbl-card {
  border-radius: var(--r-md); padding: 14px 16px;
  background-color: var(--glass-bg); background-image: linear-gradient(150deg, rgba(255,255,255,.05), rgba(255,255,255,0) 46%);
  border: 1px solid var(--glass-brd); box-shadow: var(--glass-shadow-lo), var(--inset-hi);
}
.wxs-stbl-h { margin: 0 0 12px; font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--txt-2); display: flex; align-items: center; gap: 9px; }
.wxs-stbl-badge { font-size: 11px; font-weight: 800; color: #0a1018; background: #46d18a; border-radius: 999px; padding: 1px 8px; min-width: 18px; text-align: center; }
.wxs-tbl-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.wxs-tbl { width: 100%; border-collapse: collapse; font-size: 12.5px; white-space: nowrap; }
.wxs-tbl th {
  text-align: right; font-weight: 600; font-size: 10.5px; text-transform: uppercase; letter-spacing: .3px;
  color: var(--txt-3); padding: 0 10px 8px; border-bottom: 1px solid var(--glass-brd);
}
.wxs-tbl th:first-child, .wxs-tbl td:first-child { text-align: left; }
.wxs-tbl td { padding: 7px 10px; border-bottom: 1px solid rgba(150,180,230,.07); color: var(--txt-1); text-align: right; font-variant-numeric: tabular-nums; }
.wxs-tbl tbody tr:hover { background: rgba(120,160,230,.05); }
.wxs-tbl td b { font-weight: 700; }
.wxs-tbl-empty { text-align: center !important; color: var(--txt-3); padding: 18px 0 !important; font-style: italic; }
.wxs-trd-up { color: #ff9e6a; } .wxs-trd-dn { color: #7fe6a0; } .wxs-trd-st { color: var(--txt-2); }
.wxs-int { font-weight: 700; }
.wxs-20h-graph { width: 100%; height: 280px; }
.wxs-pager { display: flex; align-items: center; justify-content: flex-end; gap: 10px; margin-top: 10px; }
.wxs-pg-btn { width: 28px; height: 28px; border-radius: 8px; border: 1px solid var(--glass-brd); background: var(--glass-bg-hi); color: var(--txt-1); font-size: 16px; line-height: 1; cursor: pointer; }
.wxs-pg-btn:disabled { opacity: .35; cursor: default; }
.wxs-pg-btn:not(:disabled):hover { border-color: rgba(120,160,230,.4); }
.wxs-pg-info { font-size: 12px; color: var(--txt-2); font-variant-numeric: tabular-nums; }
@media (max-width: 600px) { .wxs-20h-graph { height: 220px; } }

/* ---- storm tracker — TABLET-ONLY refinements (621–1024), layered over the ≤1024 mobile
   reorg above. Placed after all storm CSS so it wins by order. Mobile (≤620) and desktop
   (≥1025) are untouched. ---- */
@media (min-width: 621px) and (max-width: 1024px) {
  /* the update pill and the 3 mode toggles share ONE row directly below the map
     (update on the left · toggles on the right). Reorder the data cards so the
     last|distribution pair and full-width stats still follow tidily underneath. */
  .wxs-storm-side .wxs-update      { grid-column: span 1; order: 1; align-items: center; }
  .wxs-storm-side .wxs-sbox--modes { grid-column: span 1; order: 2; }
  .wxs-storm-side .wxs-sbox--last  { order: 3; }
  .wxs-storm-side .wxs-sbox--dist  { order: 4; }
  .wxs-storm-side .wxs-sbox--stats { order: 5; }

  /* toggles a bit larger than the phone-compact size (they now have a half-width row) */
  body:not(.wxs-smap-fs) .wxs-sbox--modes { gap: 8px 10px; padding: 8px 10px; }
  body:not(.wxs-smap-fs) .wxs-sbox--modes .wxs-modecell-l { font-size: 10px; }
  body:not(.wxs-smap-fs) .wxs-sbox--modes .wxs-mode-ic { width: 13px; height: 13px; }
  body:not(.wxs-smap-fs) .wxs-sbox--modes .wxs-switch { width: 40px; height: 23px; }
  body:not(.wxs-smap-fs) .wxs-sbox--modes .wxs-switch-track::before { width: 18px; height: 18px; }
  body:not(.wxs-smap-fs) .wxs-sbox--modes .wxs-switch input:checked + .wxs-switch-track::before { transform: translate(16px, -50%); }

  /* Active-storms + 24h-history tables: shrink + allow wrapping so all 12 columns fit
     the tablet width with no horizontal scrollbar (they overflow at ≤1024 otherwise). */
  .wxs-storm-extra .wxs-tbl { font-size: 10px; white-space: normal; }
  .wxs-storm-extra .wxs-tbl th { font-size: 8.5px; padding: 0 5px 6px; }
  .wxs-storm-extra .wxs-tbl td { padding: 5px 5px; }
  .wxs-storm-extra .wxs-tbl td:first-child { white-space: nowrap; }  /* keep the storm ID on one line */
}

/* shared top-right credits stack (Blitzortung / EUMETSAT attribution, licence) */
.wxs-map-credits {
  position: absolute; right: 10px; top: 10px; z-index: 5;
  display: flex; flex-direction: column; align-items: flex-end; gap: 6px;
}
.wxs-credit-pill {
  font-size: 10.5px; color: var(--txt-1); padding: 4px 9px; border-radius: 999px;
  background: rgba(12,20,38,.9); border: 1px solid var(--glass-brd); white-space: nowrap;
}
.wxs-credit-pill a { color: #ffd24a; text-decoration: none; }
#wxs-eum-credit a { color: #c4a0f5; }

/* MapLibre controls -> glass/dark */
.maplibregl-ctrl-group { background: var(--glass-bg-hi) !important; border: 1px solid var(--glass-brd) !important; box-shadow: var(--glass-shadow-lo) !important; }
.maplibregl-ctrl-group button { background: transparent !important; }
.maplibregl-ctrl-group button + button { border-top: 1px solid var(--glass-brd) !important; }
.maplibregl-ctrl button .maplibregl-ctrl-icon { filter: invert(1) opacity(.65); }
.maplibregl-ctrl-attrib { background: rgba(10,16,26,.55) !important; border-radius: 6px 0 0 0 !important; }
.maplibregl-ctrl-attrib a, .maplibregl-ctrl-attrib { color: var(--txt-2) !important; }

/* ================= FOOTER ================= */
/* SEO intro — a subtle, crawlable "about the station" blurb above the footer.
   Token-based so it flips with the theme; unique text per page (data-i18n). */
.wxs-seo { max-width: var(--maxw); margin: 34px auto 0; padding: 0 var(--gutter); }
.wxs-seo__txt { margin: 0 auto; max-width: 94ch; text-align: center; font-size: 13.5px; line-height: 1.75; color: var(--txt-2); }
/* live current-conditions line (server-rendered from clientraw) — a touch more prominent */
.wxs-seo__now { margin: 0 auto 10px; text-align: center; font-size: 14.5px; color: var(--txt-1); font-variant-numeric: tabular-nums; }
.wxs-seo__now strong { color: var(--txt-0); font-weight: 700; }
@media (max-width: 620px) { .wxs-seo__txt { font-size: 12.5px; text-align: left; } }

.wxs-foot {
  width: 100%; margin-top: 40px; padding: 26px var(--gutter) 32px;
  border-top: 1px solid var(--glass-brd); color: var(--txt-3); font-size: 12px; text-align: center;
}
.wxs-foot__inner { max-width: var(--maxw); margin: 0 auto; display: flex; flex-direction: column; align-items: center; gap: 7px; }
.wxs-foot__line { margin: 0; display: flex; align-items: center; justify-content: center; gap: 9px; flex-wrap: wrap; line-height: 1.5; color: var(--txt-2); }
.wxs-foot__davis { height: 17px; width: auto; opacity: .88; }
/* Davis mark is a mid-grey that reads dim on the dark footer → lighten it there
   (light theme keeps it as-is; it's dark-enough on the pale footer). */
:root[data-theme="dark"] .wxs-foot__davis { filter: brightness(1.7); }
/* Dark theme: white 3D-emboss mark (boltek-logo-v1.png) on the dark footer.
   Light theme swaps to a flat de-embossed dark version (boltek-logo-light.png,
   chosen in ui.js buildFooter) so no CSS darkening/halo is needed. */
.wxs-foot__boltek { height: 18px; width: auto; opacity: .85; }
/* Davis/Boltek footer marks link out to the makers' sites */
.wxs-foot__brandlink { display: inline-block; line-height: 0; vertical-align: middle; transition: opacity .15s; }
.wxs-foot__brandlink:hover { opacity: .7; }
.wxs-foot__logo { display: inline-block; margin-bottom: 12px; transition: opacity .15s; }
.wxs-foot__logo:hover { opacity: .8; }
.wxs-foot__logo img { display: block; height: 58px; width: auto; }
.wxs-foot__copy { margin: 9px 0 0; color: var(--txt-3); font-size: 11.5px; }
.wxs-foot__status { margin: 4px 0 0; display: flex; align-items: center; justify-content: center; gap: 9px; font-size: 11.5px; color: var(--txt-3); }
.wxs-foot__status a { color: var(--txt-2); font-weight: 600; transition: color .15s; }
.wxs-foot__status a:hover { color: var(--accent-2); }
.wxs-foot__sep { opacity: .5; }
/* visitors online (2026-10-05): a small pill on its own line under the status line - the network-wide count from
   /presence/ping.php (ui.js startPresence); hidden until the first answer */
.wxs-foot__online { margin: 8px auto 0; width: max-content; display: flex; align-items: center; gap: 6px; padding: 2px 10px; border: 1px solid var(--glass-brd); border-radius: 999px; font-size: 11.5px; font-weight: 500; color: var(--txt-2); font-variant-numeric: tabular-nums; }
.wxs-foot__online[hidden] { display: none; }
.wxs-foot__online b { font-weight: 700; color: var(--txt-1); }
.wxs-foot__online-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--good); box-shadow: 0 0 6px var(--good); }

/* ================= SYSTEM STATUS (wxstatus.php) ================= */
.wxs-st-sys { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gap); margin-bottom: 22px; }
.wxs-st-card {
  position: relative; display: flex; flex-direction: column; gap: 5px; padding: 16px 18px;
  background: var(--glass-bg); border: 1px solid var(--glass-brd); border-radius: var(--r-md);
  box-shadow: var(--glass-shadow-lo), var(--inset-hi);
}
.wxs-st-card i { font-style: normal; font-size: 12px; font-weight: 600; color: var(--txt-2); padding-right: 26px; }
.wxs-st-card b { font-size: 16px; font-weight: 800; color: var(--txt-0); line-height: 1.35; }
.wxs-st-ic { position: absolute; top: 14px; right: 14px; width: 20px; height: 20px; fill: none; stroke: var(--accent-2); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; opacity: .8; }

.wxs-st-sec { margin-bottom: 24px; }
.wxs-st-sec .wxs-graphs__title { margin: 0 0 12px; }

/* shared glass surface for the status blocks (.glasscard isn't defined) */
.wxs-st-soft, .wxs-st-metar, .wxs-st-recept {
  background: var(--glass-bg); border: 1px solid var(--glass-brd); border-radius: var(--r-md);
  box-shadow: var(--glass-shadow-lo), var(--inset-hi);
}
/* software health list */
.wxs-st-soft { padding: 4px 18px; }
.wxs-st-item { display: flex; align-items: center; gap: 13px; padding: 13px 0; border-bottom: 1px solid rgba(150,180,230,.08); }
.wxs-st-item:last-child { border-bottom: 0; }
.wxs-st-dot { width: 11px; height: 11px; flex: none; border-radius: 50%; background: var(--txt-3); }
.wxs-st-dot.is-ok { background: #46d18a; box-shadow: 0 0 8px rgba(70,209,138,.6); }
.wxs-st-dot.is-bad { background: #ff5454; box-shadow: 0 0 8px rgba(255,84,84,.6); }
.wxs-st-dot.is-unknown { background: #6b788f; }
.wxs-st-item-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.wxs-st-item-name { font-size: 14px; font-weight: 600; color: var(--txt-0); }
.wxs-st-item-name b { font-weight: 700; color: var(--accent-2); font-size: 12.5px; }
.wxs-st-item-sub { font-size: 11.5px; color: var(--txt-3); }
.wxs-st-item-state { font-size: 11px; font-weight: 800; letter-spacing: .5px; color: var(--txt-3); white-space: nowrap; }
.wxs-st-item-state.is-ok { color: #46d18a; }
.wxs-st-item-state.is-bad { color: #ff5454; }

/* METAR */
.wxs-st-metar { padding: 16px 18px; }
.wxs-st-metar-head { font-size: 12px; color: var(--txt-2); margin-bottom: 10px; }
.wxs-st-metar-head b { color: var(--txt-0); font-weight: 700; }
.wxs-st-metar-raw { display: block; font-family: ui-monospace, "Consolas", "Courier New", monospace; font-size: 13px; line-height: 1.5;
  color: #bcd0ee; word-break: break-word; background: rgba(10,16,30,.45); border: 1px solid rgba(150,180,230,.14); border-radius: 8px; padding: 11px 13px; }

/* Davis reception */
.wxs-st-recept { padding: 16px 18px; }
.wxs-st-recept-now { display: flex; align-items: baseline; gap: 9px; margin-bottom: 8px; }
.wxs-st-recept-val { font-size: 30px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--txt-0); }
.wxs-st-recept-val.is-ok { color: #46d18a; }
.wxs-st-recept-val.is-warn { color: #ffd24a; }
.wxs-st-recept-val.is-bad { color: #ff5454; }
.wxs-st-recept-now small { font-size: 12px; color: var(--txt-2); }
.wxs-st-recept-chart { width: 100%; height: 210px; }

@media (max-width: 720px) { .wxs-st-sys { grid-template-columns: 1fr; } }

/* ================= icon animations (GPU: transform/opacity only) ================= */
.wxi { overflow: visible; }
@media (prefers-reduced-motion: no-preference) {
  .wxi-rays { animation: wxiRays 36s linear infinite; }
  @keyframes wxiRays { to { transform: rotate(360deg); } }

  /* gentle continuous float — a tiny ellipse at constant speed (linear) so the
     loop is seamless (0%≡100%, no direction reversal, no stall/bump at the ends) */
  .wxi-cloud-shape { animation: wxiDrift 8s linear infinite; }
  @keyframes wxiDrift {
    0%    { transform: translate(1.4px, 0); }
    12.5% { transform: translate(0.99px, 0.57px); }
    25%   { transform: translate(0, 0.8px); }
    37.5% { transform: translate(-0.99px, 0.57px); }
    50%   { transform: translate(-1.4px, 0); }
    62.5% { transform: translate(-0.99px, -0.57px); }
    75%   { transform: translate(0, -0.8px); }
    87.5% { transform: translate(0.99px, -0.57px); }
    100%  { transform: translate(1.4px, 0); }
  }

  .wxi-drop { animation: wxiDrop 1.2s linear infinite; }
  @keyframes wxiDrop { 0% { opacity: 0; transform: translateY(-5px); } 25% { opacity: 1; } 100% { opacity: 0; transform: translateY(9px); } }

  .wxi-flake { animation: wxiFlake 2.6s linear infinite; }
  @keyframes wxiFlake { 0% { opacity: 0; transform: translate(0,-4px); } 20% { opacity: 1; } 80% { opacity: 1; } 100% { opacity: 0; transform: translate(3px,12px); } }

  /* heavy precip = faster fall (intensity via animation speed) */
  .wxi-rain--heavy .wxi-drop { animation-duration: .7s; }
  .wxi-snow--heavy .wxi-flake { animation-duration: 1.5s; }

  .wxi-bolt { animation: wxiBolt 2.8s steps(1) infinite; transform-box: fill-box; transform-origin: center; }
  @keyframes wxiBolt { 0%, 88%, 100% { opacity: 1; } 90% { opacity: .15; } 92% { opacity: 1; } 94% { opacity: .35; } 96% { opacity: 1; } }

  .wxi-star { animation: wxiTwinkle 3s ease-in-out infinite; }
  @keyframes wxiTwinkle { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }

  .wxi-fogline { animation: wxiFog 4s ease-in-out infinite; }
  @keyframes wxiFog { 0%, 100% { transform: translateX(-2px); opacity: .7; } 50% { transform: translateX(2px); opacity: 1; } }
  .wxi-fog--light { opacity: .5; }   /* mist = fainter fog lines */

  .wxi-wind { animation: wxiWind 3.2s ease-in-out infinite; }
  @keyframes wxiWind { 0%, 100% { transform: translateX(-1px); opacity: .85; } 50% { transform: translateX(2px); opacity: 1; } }
}

/* value-change flash + LED update flash */
.wxs-flash { animation: wxsValFlash 1.15s ease-out; }
@keyframes wxsValFlash {
  0%   { filter: brightness(2.3); text-shadow: 0 0 16px rgba(140,190,255,.95), 0 0 5px rgba(255,255,255,.7); }
  45%  { filter: brightness(1.45); text-shadow: 0 0 9px rgba(140,190,255,.5); }
  100% { filter: brightness(1); text-shadow: none; }
}
/* the Latest-Update line: only the time is green + flashes; the date stays white
   (matches the "Τελευταία ενημέρωση" label) — light theme already sets it white too */
.wxs-sub-date { color: var(--txt-0); }

/* mobile compact-view toggle — hidden on desktop, revealed in the ≤620 query */
.wxs-compact-toggle {
  display: none; align-items: center; gap: 6px; cursor: pointer; font: inherit;
  font-size: 11px; font-weight: 700; letter-spacing: .3px; color: var(--txt-2);
  background: var(--glass-bg); border: 1px solid var(--glass-brd); border-radius: 8px;
  padding: 4px 9px; transition: color .15s, background .15s, border-color .15s;
}
.wxs-compact-toggle svg { width: 14px; height: 14px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; }
.wxs-compact-toggle.is-on { color: var(--txt-0); background: var(--accent-soft); border-color: var(--glass-brd-hi); }
.wxs-compact-toggle.is-on svg rect { fill: currentColor; stroke: none; }

/* ================= RESPONSIVE ================= */
@media (max-width: 1100px) {
  .wxs-clock { display: none; }
}
@media (max-width: 1024px) {
  .wxs-hero { grid-column: span 12; }
  .wxs-wind, .wxs-rain, .wxs-cloudviz { grid-column: span 6; }
  .wxs-hum-col, .wxs-otd-col, .wxs-misc-col { grid-column: span 6; }
}
/* iPad-portrait tablets (621–1024px, incl. the 13" iPad Pro/Air at 1024px): rework the
   dashboard grid for the tablet zone only. Bounded on both sides so desktop (≥1025) and
   mobile (≤620) stay exactly as they are. Every grid child gets an explicit order. */
@media (min-width: 621px) and (max-width: 1024px) {
  /* row 1 — shrink the conditions/temp card; slim the sky strip and pull it up into
     the freed space beside the hero. The 12-col grid is too coarse for a fine tweak,
     so we nudge the hero↔sky boundary by a pixel amount: the hero (pinned left) gives
     up 17px of right-side dead space and the sky strip (pinned right) grows 17px left
     into it (≈ +15% wider), keeping the 13px gap and the flush right edge. */
  .wxs-hero     { grid-column: span 10; order: 1; justify-self: start; width: calc(100% - 17px); }
  .wxs-cloudviz { grid-column: span 2;  order: 2; justify-self: end;   width: calc(100% + 17px); }
  /* row 2 */
  .wxs-wind     { order: 3; }
  .wxs-rain     { order: 4; }
  /* row 3 — Humidity & Barometer swapped to the LEFT, storm-rate + records to the RIGHT */
  .wxs-hum-col  { order: 5; }
  .wxs-otd-col  { order: 6; }
  /* row 4 — misc + astronomy span the full width side-by-side so no card sits alone */
  .wxs-misc-col { grid-column: span 12; order: 7; flex-direction: row; align-items: stretch; }
  .wxs-misc-col > * { flex: 1 1 0; min-width: 0; }
}
/* Burger/drawer menu up to 1024px (matches the tablet body ceiling) — above 860 the full
   horizontal nav wrapped to 2 lines on tablets (e.g. the 13" iPad at 1024px). ≥1025 keeps
   the inline desktop nav. */
@media (max-width: 1024px) {
  .wxs-burger { display: inline-flex; }
  /* menu is now an absolute drawer (out of flow), so push the live dot + temp
     + burger to the far right, keeping the gap from the brand on the left */
  .wxs-head-right { margin-left: auto; }
  .wxs-menu {
    position: absolute; top: calc(100% + 8px); right: var(--gutter); left: var(--gutter);
    flex-direction: column; align-items: stretch; gap: 2px; padding: 8px;
    /* near-opaque so the drawer stays readable on mobile where the backdrop
       blur may not render */
    background: rgba(13, 20, 38, 0.97); border: 1px solid var(--glass-brd); border-radius: var(--r-md);
    -webkit-backdrop-filter: blur(var(--glass-blur)); backdrop-filter: blur(var(--glass-blur));
    box-shadow: var(--glass-shadow); margin: 0;
    opacity: 0; visibility: hidden; transform: translateY(-6px); transition: .18s;
  }
  /* the drawer bg is hardcoded dark → light near-opaque panel in light theme
     (scoped inside this mobile query so the desktop horizontal nav, which has no
     background, is never affected). Menu text/controls flip via their tokens. */
  :root[data-theme="light"] .wxs-menu { background: rgba(250, 252, 255, 0.97); }
  /* graphite: the mobile/tablet drawer (and the inline Stats submenu on it) go charcoal
     instead of the hardcoded navy above — the desktop dropdown is handled separately. */
  :root[data-theme="dark"][data-variant="graphite"] .wxs-menu { background: rgba(24, 24, 28, 0.97); }
  .wxs-header.is-open .wxs-menu { opacity: 1; visibility: visible; transform: none; }
  /* dropdown renders inline inside the mobile drawer */
  .wxs-menu-group { width: 100%; }
  /* Stats trigger: icon+label grouped on the left like every other item, caret pushed to the far right */
  .wxs-menu-trig { width: 100%; justify-content: flex-start; }
  .wxs-menu-trig .wxs-caret { margin-left: auto; }
  .wxs-dropdown {
    position: static; opacity: 1; visibility: visible; transform: none;
    background: transparent; border: 0; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none;
    padding: 2px 0 2px 14px; min-width: 0;
  }
  .wxs-menu-group:not(.is-open) .wxs-dropdown { display: none; }

  /* language switch leaves the header bar and moves into the drawer; the live
     clock + coordinates ride along with it (header right keeps dot+temp+burger) */
  .wxs-lang, .wxs-theme { display: none; }
  .wxs-menu-extra {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    width: 100%; margin-top: 6px; padding: 9px 4px 2px;
    border-top: 1px solid var(--glass-brd);
  }
  .wxs-menu-ctrls { display: flex; align-items: center; gap: 8px; flex: none; flex-wrap: wrap; justify-content: flex-end; }
  .wxs-menu-meta { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
  .wxs-menu-clock { font-size: 13.5px; font-weight: 700; color: var(--txt-1); font-variant-numeric: tabular-nums; }
  .wxs-menu-geo { font-size: 10.5px; color: var(--txt-3); line-height: 1.55; }
  .wxs-menu-geo b { color: var(--txt-1); font-weight: 600; }
  /* lat / lon / elevation each on its own line in the drawer (subbar stays inline) */
  .wxs-menu-geo .wxs-geo-i { display: block; }
  .wxs-menu-geo .wxs-geo-x { display: none; }
  .wxs-menu-lang, .wxs-menu-theme {
    display: inline-flex; align-items: center; gap: 6px; flex: none; cursor: pointer;
    font: inherit; font-size: 12px; font-weight: 700; color: var(--txt-1);
    background: var(--glass-bg-lo); border: 1px solid var(--glass-brd); border-radius: 9px;
    padding: 8px 11px;
  }
  .wxs-menu-lang:hover, .wxs-menu-theme:hover { color: var(--txt-0); border-color: var(--glass-brd-hi); }
  .wxs-menu-lang .wxs-mi, .wxs-menu-theme .wxs-mi { width: 16px; height: 16px; flex: none; }
}
@media (max-width: 620px) {
  /* ===== mobile reflow: pair wind|rain and humbaro|cloud on shared rows =====
     flatten the two stacking wrappers so their cards become direct grid items,
     then sequence everything with `order`. Scoped to phones — desktop untouched. */
  .wxs-dash { grid-template-columns: 1fr 1fr; }
  .wxs-otd-col, .wxs-misc-col, .wxs-hum-col { display: contents; }
  .wxs-hero     { grid-column: 1 / -1; order: 1; }
  .wxs-wind     { grid-column: span 1;  order: 2; }
  .wxs-rain     { grid-column: span 1;  order: 3; }
  /* Humidity + Barometer stacked (mini) in col 1; the sky tube row-spans both on the
     right so the pair sits at the same level as the cloud graph. */
  .wxs-humid    { grid-column: 1;      order: 4; }
  .wxs-cloudviz { grid-column: 2;      order: 5; grid-row: span 2; }
  .wxs-barom    { grid-column: 1;      order: 6; }
  .wxs-firewx   { grid-column: 1 / -1; order: 7; }
  /* wider sky-tube on mobile → parameter toggle tucks into the bottom-LEFT corner and
     the ECMWF model credit into the bottom-RIGHT (opposite corners = no collision) */
  .wxs-cloudviz__params { bottom: 6px; gap: 3px; justify-content: flex-start; padding-left: 7px; }
  .wxs-cloudviz__params .wxs-cvparam { width: 18px; height: 18px; }
  .wxs-cloudviz__params .wxs-cvparam svg { width: 12px; height: 12px; }
  .wxs-cloudviz__src,
  .wxs-cloudviz__run { left: auto; right: 7px; text-align: right; }
  .wxs-ltact    { grid-column: 1 / -1; order: 8; }
  .wxs-misc     { grid-column: 1 / -1; order: 9; }
  .wxs-astro    { grid-column: 1 / -1; order: 10; }
  .wxs-otd-pair { grid-column: 1 / -1; order: 11; }

  /* compact the half-width cards */
  .wxs-wind, .wxs-rain, .wxs-humid, .wxs-barom { padding: 13px 11px; }
  .wxs-wind .wxs-card__title, .wxs-rain .wxs-card__title, .wxs-humid .wxs-card__title, .wxs-barom .wxs-card__title { font-size: 10px; margin-bottom: 6px; }
  /* mini Humidity/Baro: value + bar (left) | max/min (right), same shape as desktop, shrunk */
  .wxs-humid .wxs-hbx, .wxs-barom .wxs-hbx { flex: 1; flex-wrap: nowrap; gap: 7px; margin-top: 0; }
  .wxs-humid .wxs-hbx__main, .wxs-barom .wxs-hbx__main { flex: 1 1 auto; min-width: 0; }
  .wxs-humid .wxs-hbx__val, .wxs-barom .wxs-hbx__val { white-space: nowrap; }
  .wxs-humid .wxs-hbx__val b { font-size: 17px; }
  .wxs-barom .wxs-hbx__val b { font-size: 15px; }     /* baro value is longer ("1009.9 hPa") — keep it on one line */
  .wxs-humid .wxs-hbx__u, .wxs-barom .wxs-hbx__u { font-size: 8.5px; }
  .wxs-humid .wxs-hbx__bar, .wxs-barom .wxs-hbx__bar { height: 5px; margin-top: 6px; }
  .wxs-hbx__mm { gap: 3px; }
  .wxs-hbx__mm .wxs-kv i { font-size: 8px; }
  .wxs-hbx__mm .wxs-kv__v b { font-size: 9.5px; }
  .wxs-hbx__mm .wxs-kv__v em { display: none; }        /* drop the time to fit the mini cards */
  .wxs-barom__sub { margin-top: 4px; gap: 4px; }   /* font-size handled by the cqi clamp on the base rule (scales to fit the ~83px mobile column) */

  /* WIND — vertical: compass over speed/gust, then Bft, then the gust rows */
  .wxs-wind__top { flex-direction: column; gap: 8px; }
  .wxs-wind__big { flex: none; width: 100%; }
  .wxs-wind .wxs-compass { width: 66px; height: 66px; }
  .wxs-wind__dir { font-size: 14px; margin-bottom: 5px; }
  .wxs-wind__bigrow { gap: 10px; }
  .wxs-wind .wxs-bigval__num { font-size: 20px; }
  .wxs-wind .wxs-bigval-sep { font-size: 19px; line-height: 20px; }
  .wxs-wind .wxs-bigval__u { font-size: 9px; }
  .wxs-wind .wxs-bigval label { font-size: 9.5px; }
  .wxs-wind__bft { font-size: 11px; margin-top: 8px; padding-bottom: 9px; margin-bottom: 9px; }
  .wxs-wind .wxs-rows--sm .wxs-kv i { font-size: 9px; }
  .wxs-wind .wxs-rows--sm .wxs-kv b { font-size: 10px; white-space: nowrap; }   /* keep "14.8 km/h · ΝΔ" on one line */

  /* RAIN — vertical: big today over the rate rows, then the totals */
  .wxs-rain__top { flex-direction: column; align-items: stretch; gap: 7px; padding-bottom: 9px; margin-bottom: 9px; }
  .wxs-rain__hero { text-align: center; }
  .wxs-rain__big { font-size: 30px; }
  .wxs-rain__rates .wxs-kv i, .wxs-rain__rates .wxs-kv b { font-size: 10px; }
  .wxs-rain .wxs-rows--sm .wxs-kv i { font-size: 9px; }
  .wxs-rain .wxs-rows--sm .wxs-kv b { font-size: 10px; white-space: nowrap; }
  .wxs-rain .wxs-rows--sm .wxs-kv--accent b { font-size: 12px; }   /* Storm total on one line */
  .wxs-rain .wxs-raindays { font-size: 10px; }

  /* HUMIDITY/BAROMETER — already a vertical list, just tighten + keep values on one line */
  .wxs-humbaro .wxs-hb3 { gap: 6px; }
  .wxs-humbaro .wxs-kv i { font-size: 10px; }
  .wxs-humbaro .wxs-kv b { font-size: 11px; }
  .wxs-humbaro .wxs-kv__v { white-space: nowrap; }
  .wxs-humbaro .wxs-hb3__mx .wxs-kv__v b, .wxs-humbaro .wxs-hb3__mn .wxs-kv__v b { font-size: 9.5px; }
  .wxs-humbaro .wxs-kv__v em { font-size: 8.5px; }

  .wxs-hero__body { flex-wrap: wrap; }
  /* mobile: give the weather icon + thermometer a bit more presence */
  .wxs-hero__icon { width: 78px; height: 78px; margin: 0; position: absolute; top: 0; left: 0; }
  .wxs-thermo { width: 66px; }
  .wxs-thermo-svg { height: 224px; }
  .wxs-clock, .wxs-live-txt { display: none; }
  /* header live pill: smaller rotating value/unit, and the ●LIVE dot + last-update
     time+date drop onto a line BELOW the pill (the subbar's stamp moves up here) */
  /* header: rotating value + temp on the SAME line (rot left, temp right); ●LED+update
     one line below. rot sits in a FIXED-WIDTH slot with its content right-aligned, so
     temp never moves as the value changes (no jiggle). */
  .wxs-head-right {
    display: grid; align-items: center; column-gap: 6px; row-gap: 2px; justify-items: start;
    grid-template-columns: auto auto auto;
    grid-template-areas: "rot temp burger" "live live burger";
  }
  .wxs-head-rot { grid-area: rot; width: 96px; justify-content: flex-end; overflow: visible; font-size: 10px; }
  .wxs-head-temp { grid-area: temp; }
  .wxs-head-main { font-size: 17px; }
  .wxs-live { grid-area: live; justify-self: end; }   /* update time to the RIGHT, near the burger */
  .wxs-head-upd { display: inline-flex; }
  .wxs-burger { grid-area: burger; align-self: center; justify-self: end; }
  /* subbar becomes a minimal centered row holding ONLY the home pill (mirrors the desktop
     subbar pill; replaces the mobile floating FAB). Coords + last-update stay hidden here --
     coords live in the drawer, the update time is in the header. */
  .wxs-subbar { display: flex; justify-content: center; }
  .wxs-subbar .wxs-sub-geo, .wxs-subbar .wxs-sub-update { display: none; }
  .wxs-sub-home { display: inline-flex; }

  /* Conditions/Temperature box: centre the whole stack on mobile */
  /* icon pinned on its own in the upper-left corner (absolute, above); the title +
     condition text are CENTRED on the temperature below — padding-left clears the
     thermometer column so the head lines up with the centred temp (not the card centre) */
  .wxs-hero__head { justify-content: center; align-items: flex-start; text-align: center; min-height: 72px; margin-bottom: 6px; padding-left: 82px; }
  .wxs-hero__main { width: 100%; }
  .wxs-hero__top { align-items: center; }
  .wxs-hero__tempbox { align-items: center; }
  .wxs-hero__metrics { align-items: center; text-align: center; padding-left: 0; border-left: 0; }
  .wxs-hero__metrics .wxs-metric { justify-content: center; }
  /* feels: comfort pill ABOVE, centred, a touch smaller */
  .wxs-hero__feels { flex-direction: column; align-items: center; gap: 4px; }

  /* compact view retired for now — button hidden (all compact CSS/JS kept intact
     below so it can be re-enabled later). Was: display: inline-flex + floated. */
  .wxs-compact-toggle {
    display: none; position: absolute; right: 12px; bottom: 12px; z-index: 4; margin: 0;
    background: rgba(10,16,30,.62);
    -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  }
  .wxs-sub-geo { display: none; }

  /* ====================================================================
     COMPACT VIEW — one-screen glance at the 4 core cards (mobile only).
     Everything is scoped to body.wxs-compact INSIDE this media query, so
     the desktop layout (and the standard mobile view) are never touched.
     ==================================================================== */
  body.wxs-compact .wxs-graphs,
  body.wxs-compact .wxs-forecast,
  body.wxs-compact .wxs-media,
  body.wxs-compact .wxs-otd-col,
  body.wxs-compact .wxs-misc-col { display: none; }

  /* the banner photo is dropped in compact mode, but the section stays as a
     slim strip so its compact toggle remains visible to switch back. The
     !important beats banner.js's inline margin-top/min-height pull-up. */
  body.wxs-compact .wxs-banner {
    margin-top: 0 !important; min-height: 0 !important; height: auto !important;
    overflow: visible; display: flex; justify-content: flex-end; padding: 6px 12px 0;
  }
  body.wxs-compact .wxs-banner__stage,
  body.wxs-compact .wxs-banner__txt,
  body.wxs-compact .wxs-banner__brand,
  body.wxs-compact .wxs-banner__credit,
  body.wxs-compact .wxs-banner::after { display: none; }
  body.wxs-compact .wxs-compact-toggle { position: static; right: auto; bottom: auto; }

  body.wxs-compact .wxs-dash { grid-template-columns: 1fr 1fr; gap: 8px; }
  body.wxs-compact .wxs-hero,
  body.wxs-compact .wxs-humbaro { grid-column: 1 / -1; }
  body.wxs-compact .wxs-wind,
  body.wxs-compact .wxs-rain { grid-column: span 1; }

  body.wxs-compact .wxs-card { padding: 11px 12px; }
  body.wxs-compact .wxs-card__title { margin-bottom: 7px; font-size: 10px; gap: 6px; }
  body.wxs-compact .wxs-card__ic { width: 15px; height: 15px; }

  /* HERO: condition + big temp + feels; drop thermometer / max-min / extra metrics */
  body.wxs-compact .wxs-thermo,
  body.wxs-compact .wxs-mm,
  body.wxs-compact .wxs-hero__kicker,
  body.wxs-compact .wxs-cloud-obs,
  body.wxs-compact .wxs-hero .wxs-metric { display: none; }
  body.wxs-compact .wxs-hero__head { margin-bottom: 4px; }
  body.wxs-compact .wxs-hero__top { gap: 8px; margin-bottom: 0; }
  body.wxs-compact .wxs-hero__temp { font-size: 46px; }
  body.wxs-compact .wxs-hero__deg { font-size: 19px; }
  body.wxs-compact .wxs-hero__feels b { font-size: 18px; }

  /* WIND: compass over speed/gust over Bft (stacked to fit the half-width) */
  body.wxs-compact .wxs-wind .wxs-rows--sm { display: none; }
  body.wxs-compact .wxs-wind__top { flex-direction: column; align-items: center; gap: 7px; }
  body.wxs-compact .wxs-wind__compass { width: 60px; height: 60px; }
  body.wxs-compact .wxs-wind__big { text-align: center; }
  body.wxs-compact .wxs-wind__bigrow { justify-content: center; }
  body.wxs-compact .wxs-bigval__num { font-size: 21px; }
  body.wxs-compact .wxs-wind__bft { font-size: 10.5px; margin-top: 6px; text-align: center; }

  /* RAIN: big today over the rate rows (stacked so the rates aren't clipped) */
  body.wxs-compact .wxs-rain .wxs-rows--sm { display: none; }
  body.wxs-compact .wxs-rain__top { flex-direction: column; align-items: stretch; gap: 7px; }
  body.wxs-compact .wxs-rain__big { font-size: 30px; }

  /* HUMIDITY/BAROMETER: humidity & baro (+trend/rate) in a 2×2; drop max/min */
  body.wxs-compact .wxs-humbaro { display: block; }
  body.wxs-compact .wxs-humbaro .wxs-hb3 { display: grid; grid-template-columns: 1fr 1fr; gap: 7px 18px; }
  body.wxs-compact .wxs-humbaro .wxs-hb3__mx,
  body.wxs-compact .wxs-humbaro .wxs-hb3__mn,
  body.wxs-compact .wxs-humbaro .wxs-hb3__sep { display: none; }
}

/* Narrow phones (Galaxy S8+ / A54 ~360px, iPhone SE ~375px): brand + rotating value +
   temp + burger no longer fit the padded header row, so the whole right group is pushed
   past the header's right edge and the burger ends up flush against the screen. Trim the
   header VALUE fonts and the burger slightly to claw that width back. Placed after the
   ≤620 block so it overrides the mobile sizes; phones ≥389px (iPhone 12–16, Pro Max)
   keep those sizes exactly as they are. */
@media (max-width: 388px) {
  .wxs-head-right  { column-gap: 5px; }
  .wxs-head-rot    { width: 76px; font-size: 9px; gap: 3px; }   /* was 96px / 10px */
  .wxs-head-wind   { width: 10px; height: 10px; }
  .wxs-head-main   { font-size: 15px; }                          /* was 17px */
  .wxs-live        { gap: 5px; }
  .wxs-live-dot    { width: 7px; height: 7px; }
  .wxs-head-upd-t  { font-size: 10px; }                          /* was 11px */
  .wxs-head-upd-d  { font-size: 9px; }                           /* was 10px */
  .wxs-burger      { width: 31px; height: 29px; border-radius: 8px; gap: 3.5px; }
  .wxs-burger span { width: 14px; }
}

/* Super-small / older phones (iPhone SE 1st gen & 5/5S, early Androids — ~320px):
   even after the ≤388 trims the header is still ~37px over budget, because the brand
   block (logo + station name + area) alone eats ~131px of a ~300px usable row. So here
   we also scale the BRAND down and take the values + burger one further notch. Scoped
   to ≤340px, so the common 360–375px phones (Galaxy S8+, iPhone SE 2/3) keep the ≤388
   sizes and everything ≥389px stays completely untouched. */
@media (max-width: 340px) {
  /* brand: smaller logo + station name, tighter divider */
  .wxs-brand             { gap: 7px; }
  .wxs-brand__logo       { height: 26px; }
  .wxs-brand__txt        { padding-left: 7px; }
  .wxs-brand__txt strong { font-size: 13px; }                    /* was 15px */
  .wxs-brand__txt small  { font-size: 9.5px; }                   /* was 11px */
  /* header values + burger: one notch below the ≤388 tier */
  .wxs-head-right        { column-gap: 4px; }
  .wxs-head-rot          { width: 66px; font-size: 8.5px; gap: 2px; }
  .wxs-head-wind         { width: 9px; height: 9px; }
  .wxs-head-main         { font-size: 13.5px; }
  .wxs-head-upd-t        { font-size: 9px; }
  .wxs-head-upd-d        { font-size: 8px; }
  .wxs-live-dot          { width: 6px; height: 6px; }
  .wxs-burger            { width: 28px; height: 27px; border-radius: 7px; gap: 3px; }
  .wxs-burger span       { width: 13px; }
}

/* ================= NOAA REPORTS ================= */
.wxs-noaa { max-width: 1060px; }
.wxs-noaa__controls { display: flex; flex-wrap: wrap; gap: 14px; margin: 4px 0 16px; }
.wxs-noaa__ctrl { display: flex; flex-direction: column; gap: 5px; font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--txt-2); }
.wxs-sel {
  font: inherit; font-size: 13px; font-weight: 600; color: var(--txt-1);
  padding: 8px 30px 8px 12px; border-radius: 10px; cursor: pointer; appearance: none; -webkit-appearance: none;
  border: 1px solid var(--glass-brd); min-width: 150px;
  background: var(--glass-bg-hi) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 10 10'><path d='M2 3.5l3 3 3-3' stroke='%238fa0bb' stroke-width='1.4' fill='none' stroke-linecap='round'/></svg>") no-repeat right 11px center;
}
.wxs-sel:hover { border-color: rgba(120,160,230,.4); }
.wxs-sel:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(70,209,138,.35); }
.wxs-sel option { background: #0c1426; color: var(--txt-1); }
.wxs-noaa__zoom { display: flex; gap: 6px; align-self: flex-end; margin-left: auto; }
.wxs-zbtn {
  width: 34px; height: 34px; border-radius: 9px; cursor: pointer; line-height: 1;
  background: var(--glass-bg-hi); border: 1px solid var(--glass-brd); color: var(--txt-1);
  font-size: 13px; font-weight: 700;
}
.wxs-zbtn:hover { border-color: rgba(120,160,230,.4); color: var(--txt-0); }
.wxs-zbtn:active { background: var(--accent-soft); }
.wxs-noaa__report { padding: 16px 18px; }
.wxs-noaa__rtitle { font-size: 15px; font-weight: 800; color: var(--txt-0); letter-spacing: .3px; text-align: center; margin-bottom: 12px; padding-bottom: 11px; border-bottom: 1px dashed rgba(120,150,200,.16); }
.wxs-noaa__pre {
  margin: 0 auto; width: -moz-fit-content; width: fit-content; max-width: 100%;
  overflow-x: auto; -webkit-overflow-scrolling: touch; white-space: pre; tab-size: 4;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  font-size: 12px; line-height: 1.7; color: var(--txt-1);
}
.wxs-noaa__msg { color: var(--txt-2); font-size: 13px; padding: 6px 0; }
.wxs-noaa__msg--empty { color: var(--txt-3); font-style: italic; }
@media (max-width: 560px) { .wxs-noaa__pre { font-size: 10px; } .wxs-sel { min-width: 132px; } }

/* ================= SATELLITE ================= */
.wxs-sat { max-width: 1200px; }                  /* close to the menu width (--maxw 1320) */
.wxs-satcard { position: relative; padding: 0; overflow: hidden; border-radius: var(--r-md); }
.sat-stage { position: relative; aspect-ratio: 800 / 763; background: #060a14; }
.sat-frame { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; image-rendering: auto; }
.sat-frame.is-on { opacity: 1; }                 /* instant frame swap (crisp fast-forward) */
/* dashboard preview renders through ONE canvas (see satellite.js) instead of stacked
   <img>s, to avoid the first-load flicker from iOS evicting opacity:0 frame bitmaps */
.sat-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.sat-top {
  position: absolute; top: 0; left: 0; right: 0; z-index: 2; pointer-events: none;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 11px 14px; font-size: 12.5px; font-weight: 600; color: #eaf0fb;
  background: linear-gradient(180deg, rgba(4,8,18,.62), transparent);
}
.sat-label { display: inline-flex; align-items: center; gap: 6px; letter-spacing: .2px; }
.sat-time { font-variant-numeric: tabular-nums; color: var(--accent); }
.sat-source { position: absolute; left: 13px; bottom: 11px; z-index: 2; pointer-events: none;
  font-size: 11px; font-weight: 600; color: rgba(255,255,255,.68); text-shadow: 0 1px 4px rgba(0,0,0,.7); }
.sat-brand { position: absolute; right: 13px; bottom: 11px; z-index: 2; pointer-events: none;
  font-size: 12.5px; font-weight: 800; letter-spacing: -.2px; color: rgba(255,255,255,.82); text-shadow: 0 1px 4px rgba(0,0,0,.7); }

/* ================= DETAILED HISTORY ================= */
.wxs-hist { max-width: 1280px; }
.wxs-hist__report { padding: 14px 16px 16px; }
.wxs-hist__host { display: flex; flex-direction: column; gap: 14px; }

/* per-day card */
.wxs-hist-day { border: 1px solid var(--glass-brd); border-radius: 13px; background: rgba(255,255,255,.018); padding: 13px 16px 15px; }
.wxs-hist-day__head { display: flex; align-items: center; gap: 12px; margin-bottom: 11px; }
.wxs-hist-day__num { font-size: 16px; font-weight: 800; color: var(--txt-0); background: var(--accent-soft); border: 1px solid rgba(70,209,138,.22); border-radius: 9px; padding: 3px 11px; font-variant-numeric: tabular-nums; }
.wxs-hist-day__date { font-size: 13px; font-weight: 600; color: var(--txt-2); text-transform: capitalize; }

/* body: stats | reserved graph slot, side by side at all times so the stats
   keep the same column layout whether the graph is shown or hidden */
.wxs-hist-day__body { display: flex; gap: 20px; align-items: flex-start; }
.wxs-hist-stats { flex: 1 1 auto; min-width: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(218px, 1fr)); gap: 0 26px; align-content: start; }
.wxs-hist-stat { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; padding: 4px 0; border-bottom: 1px solid rgba(120,150,200,.07); font-size: 12.5px; line-height: 1.4; }
.wxs-hist-stat .k { color: var(--txt-2); flex: 1 1 auto; min-width: 0; }
.wxs-hist-stat .v { color: var(--txt-0); font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.wxs-hist-stat .m { flex-basis: 100%; color: var(--txt-3); font-size: 10.5px; line-height: 1.2; }
.wxs-hist-stat.max .v { color: #ff9a8d; }
.wxs-hist-stat.min .v { color: #82b4ff; }

/* fire weather index — compact chips spanning the grid */
.wxs-hist-fwi { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 7px; margin-top: 11px; padding-top: 11px; border-top: 1px dashed rgba(120,150,200,.16); }
.wxs-hist-fwi__t { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--txt-2); }
.wxs-hist-chip { font-size: 11.5px; color: var(--txt-1); background: var(--glass-bg-hi); border: 1px solid var(--glass-brd); border-radius: 7px; padding: 2px 9px; font-variant-numeric: tabular-nums; }
.wxs-hist-chip b { color: var(--txt-2); font-weight: 700; }

/* graph slot — width reserved beside the stats at all times; the image only
   appears once toggled (so the stats layout never shifts) */
.wxs-hist-graph { flex: 0 0 466px; max-width: 44%; align-self: flex-start; }
.wxs-hist-graph > * { display: none; }
.wxs-hist-graph.is-shown > * { display: block; }
.wxs-hist-img { width: 100%; height: auto; border-radius: 10px; border: 1px solid var(--glass-brd); background: #0c1322; }
.wxs-hist-gna { color: var(--txt-3); font-style: italic; font-size: 12px; padding: 8px 2px; }

/* graph toggle button */
.wxs-hist-gbtn {
  display: inline-flex; align-items: center; gap: 7px; margin-left: auto;
  font: inherit; font-size: 12px; font-weight: 600; color: var(--accent);
  background: var(--accent-soft); border: 1px solid rgba(70,209,138,.3); border-radius: 8px; padding: 5px 12px; cursor: pointer; transition: .15s;
}
.wxs-hist-gbtn:hover { background: rgba(70,209,138,.16); border-color: rgba(70,209,138,.5); }
.wxs-hist-gbtn.is-open { color: var(--txt-0); background: rgba(120,160,230,.16); border-color: rgba(120,160,230,.42); }
.wxs-hist-gic { width: 14px; height: 14px; flex: none; background: currentColor;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M3 3v18h18' fill='none' stroke='black' stroke-width='2'/><path d='M7 14l4-4 3 3 4-6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>") center/contain no-repeat;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M3 3v18h18' fill='none' stroke='black' stroke-width='2'/><path d='M7 14l4-4 3 3 4-6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>") center/contain no-repeat; }

/* end-of-month summary card (accent-tinted, full-width stat grid) */
.wxs-hist-sum { border: 1px solid rgba(70,209,138,.3); border-radius: 13px; padding: 14px 16px 16px;
  background: linear-gradient(180deg, rgba(70,209,138,.07), rgba(70,209,138,.02)); }
.wxs-hist-sum__head { display: flex; align-items: center; gap: 11px; flex-wrap: wrap; margin-bottom: 13px; }
.wxs-hist-sum__ic { width: 19px; height: 19px; flex: none; background: var(--accent);
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><rect x='3' y='4.5' width='18' height='16' rx='2' fill='none' stroke='black' stroke-width='2'/><path d='M3 9h18M8 2.5v4M16 2.5v4' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'/></svg>") center/contain no-repeat;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><rect x='3' y='4.5' width='18' height='16' rx='2' fill='none' stroke='black' stroke-width='2'/><path d='M3 9h18M8 2.5v4M16 2.5v4' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'/></svg>") center/contain no-repeat; }
.wxs-hist-sum__title { font-size: 15px; font-weight: 800; color: var(--txt-0); letter-spacing: .2px; }
.wxs-hist-sum__sub { font-size: 13px; font-weight: 600; color: var(--accent); }
.wxs-hist-sum__stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(218px, 1fr)); gap: 0 26px; align-content: start; }
.wxs-hist-rain { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; margin-top: 13px; padding-top: 12px; border-top: 1px dashed rgba(120,150,200,.18); }
.wxs-hist-rain__t { width: 100%; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--txt-2); margin-bottom: 3px; }
.wxs-hist-rain .wxs-hist-chip b { color: var(--txt-0); }

@media (max-width: 720px) {
  .wxs-hist-day__body { flex-direction: column; }
  .wxs-hist-graph { max-width: 100%; flex-basis: auto; width: 100%; }
}

/* ================= MONTHLY CLIMATE REPORT ================= */
.wxs-clim { max-width: 1200px; }
.wxs-clim-rhead { display: flex; align-items: baseline; flex-wrap: wrap; gap: 10px 14px; margin: 2px 0 16px; }
.wxs-clim-rtitle { font-size: 20px; font-weight: 800; color: var(--txt-0); letter-spacing: .2px; text-transform: capitalize; }
.wxs-clim-badges { display: inline-flex; flex-wrap: wrap; gap: 7px; }
.wxs-clim-badge { font-size: 10.5px; font-weight: 700; letter-spacing: .3px; padding: 3px 10px; border-radius: 999px; border: 1px solid; }
.wxs-clim-badge--legacy { color: #ffcf8a; background: rgba(255,180,90,.1); border-color: rgba(255,180,90,.32); cursor: help; }
.wxs-clim-badge--partial { color: #9fb6dd; background: rgba(120,160,230,.1); border-color: rgba(120,160,230,.3); cursor: help; }
.wxs-clim-badge--current { color: #79e6b3; background: rgba(70,209,138,.1); border-color: rgba(70,209,138,.32); }

/* one row per parameter: [ data card | wide daily chart ] */
.wxs-clim-rows { display: flex; flex-direction: column; gap: var(--gap); }
.wxs-clim-row { display: grid; grid-template-columns: minmax(232px, 280px) minmax(0, 1fr); gap: var(--gap); align-items: stretch; }

.wxs-clim-card {
  display: flex; flex-direction: column; border-radius: var(--r-md); padding: 14px 16px 12px;
  background-color: var(--glass-bg); background-image: linear-gradient(150deg, rgba(255,255,255,.045), rgba(255,255,255,0) 46%);
  border: 1px solid var(--glass-brd); box-shadow: var(--glass-shadow-lo), var(--inset-hi);
  border-left: 2px solid var(--acc, var(--accent));
}
.wxs-clim-card__hd { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.wxs-clim-card__dot { width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--acc, var(--accent)); box-shadow: 0 0 8px var(--acc, var(--accent)); }
.wxs-clim-card__hd h3 { margin: 0; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--txt-2); }
.wxs-clim-card__rows { display: flex; flex-direction: column; justify-content: center; flex: 1 1 auto; }
.wxs-clim-kv { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 5px 0; font-size: 13px; }
.wxs-clim-kv + .wxs-clim-kv { border-top: 1px solid rgba(150,180,230,.08); }
.wxs-clim-kv i { color: var(--txt-2); font-style: normal; }
.wxs-clim-kv b { color: var(--txt-0); font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right; }
.wxs-clim-kv b em { color: var(--txt-3); font-style: normal; font-weight: 600; font-size: 10.5px; margin-left: 3px; }

.wxs-clim-chartcard {
  display: flex; flex-direction: column; min-width: 0; border-radius: var(--r-md); padding: 12px 14px 8px;
  background-color: var(--glass-bg); border: 1px solid var(--glass-brd); box-shadow: var(--glass-shadow-lo), var(--inset-hi);
}
.wxs-clim-charthd { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 4px; }
.wxs-clim-charttitle { font-size: 11px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase; color: var(--txt-2); }
.wxs-clim-chartval { font-size: 15px; font-weight: 800; color: var(--txt-0); font-variant-numeric: tabular-nums; }
.wxs-clim-chartvallbl { font-style: normal; font-size: 9.5px; font-weight: 600; letter-spacing: .3px; text-transform: uppercase; color: var(--txt-2); opacity: .7; margin-right: 5px; }
.wxs-clim-chart { width: 100%; min-width: 0; flex: 1 1 auto; min-height: 208px; }
@media (max-width: 760px) {
  .wxs-clim-row { grid-template-columns: 1fr; }
  .wxs-clim-chart { min-height: 200px; }
}

/* ================= STATION RECORDS ================= */
.wxs-rec-page { max-width: 1160px; }
.wxs-rec-host { display: flex; flex-direction: column; gap: 20px; margin-top: 6px; }
.wxs-rec-group { --acc: #6f8fbf; }
.wxs-rec-gtitle { display: flex; align-items: center; gap: 9px; font-size: 12px; font-weight: 800; letter-spacing: .8px; text-transform: uppercase; color: var(--txt-1); margin: 0 0 10px; }
.wxs-rec-gtitle::before { content: ""; width: 9px; height: 9px; border-radius: 3px; background: var(--acc); box-shadow: 0 0 10px var(--acc); }
.wxs-rec-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(248px, 1fr)); gap: 11px; }

.wxs-rec { display: flex; align-items: flex-start; gap: 11px; padding: 13px 15px; border-radius: var(--r-md);
  background: var(--glass-bg); border: 1px solid var(--glass-brd); box-shadow: var(--glass-shadow-lo), var(--inset-hi);
  border-left: 3px solid var(--acc); transition: transform .14s, border-color .14s; }
.wxs-rec:hover { transform: translateY(-2px); border-left-color: var(--acc); }
.wxs-rec-gl { flex: none; width: 26px; height: 26px; display: grid; place-items: center; border-radius: 8px;
  font-size: 12px; font-weight: 800; color: var(--acc); background: color-mix(in srgb, var(--acc) 14%, transparent); }
.wxs-rec-main { min-width: 0; flex: 1 1 auto; }
.wxs-rec-label { display: flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 600; color: var(--txt-2); line-height: 1.25; }
.wxs-rec-val { font-size: 22px; font-weight: 800; color: var(--txt-0); font-variant-numeric: tabular-nums; margin: 3px 0 1px; letter-spacing: -.3px; }
.wxs-rec-when { font-size: 11px; font-weight: 700; color: var(--txt-2); opacity: .95; font-variant-numeric: tabular-nums; letter-spacing: .1px; }
.wxs-rec-tag { flex: none; font-size: 8.5px; font-weight: 800; letter-spacing: .3px; padding: 1px 5px; border-radius: 5px;
  color: #9fb6dd; background: rgba(120,160,230,.13); border: 1px solid rgba(120,160,230,.3); cursor: help; }
.wxs-rec-tag--approx { color: #cdb8f0; background: rgba(155,140,240,.13); border-color: rgba(155,140,240,.32); }

.wxs-rec-legend { display: flex; flex-wrap: wrap; gap: 16px; margin: 16px 2px 0; }
.wxs-rec-lg { font-size: 11px; color: var(--txt-2); display: inline-flex; align-items: center; gap: 6px; }
.wxs-rec-lg b { font-size: 9px; font-weight: 800; padding: 1px 5px; border-radius: 5px; color: #9fb6dd; background: rgba(120,160,230,.13); border: 1px solid rgba(120,160,230,.3); }
@media (max-width: 560px) { .wxs-rec-grid { grid-template-columns: 1fr; } }

/* ================= DETAILED TABLES ================= */
.wxs-tables { max-width: 1200px; }
.wxs-tbl-controls { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 14px; margin: 4px 0 16px; }
.wxs-seg { display: inline-flex; gap: 3px; padding: 3px; border-radius: 11px; background: var(--glass-bg-hi); border: 1px solid var(--glass-brd); }
.wxs-seg button { font: inherit; font-size: 13px; font-weight: 700; color: var(--txt-2); padding: 7px 17px; border: 0; border-radius: 8px; background: transparent; cursor: pointer; transition: .15s; }
.wxs-seg button:hover { color: var(--txt-1); }
.wxs-seg button.is-active { background: var(--accent-soft); color: var(--txt-0); }

.wxs-tbl-msg { color: var(--txt-2); font-size: 13px; padding: 8px 2px; display: none; }
.wxs-tbl-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: 14px; border: 1px solid var(--glass-brd); background: var(--glass-bg); }
.wxs-dtables:empty { display: none; }
.wxs-dt-title { font-size: 13px; font-weight: 800; color: var(--txt-0); letter-spacing: .3px; margin: 22px 14px 9px; }
.wxs-dt-title:first-child { margin-top: 12px; }
.wxs-dtable { border-collapse: separate; border-spacing: 0; width: 100%; font-size: 11px; }
.wxs-dtable + .wxs-dt-title { border-top: 1px solid rgba(120,150,200,.12); padding-top: 18px; }
.wxs-dtable th, .wxs-dtable td { text-align: center; padding: 4px 7px; white-space: nowrap; }

/* sticky header row */
.wxs-dtable thead th { position: sticky; top: 0; z-index: 3; background: #101a2c; color: var(--txt-1); font-weight: 700; border-bottom: 1px solid rgba(120,150,200,.2); }
.wxs-dt-mon { color: var(--txt-0); }
.wxs-dt-sub { font-size: 10px; color: var(--txt-2); font-weight: 600; padding-top: 2px; padding-bottom: 2px; }

/* sticky day / label column */
.wxs-dt-corner, .wxs-dt-day, .wxs-dt-foot { position: sticky; left: 0; z-index: 2; background: #101a2c; color: var(--txt-1); font-weight: 700; }
.wxs-dt-corner { top: 0; z-index: 4; }
.wxs-dt-day { font-size: 11px; color: var(--txt-2); }
.wxs-dt-foot { text-align: right; font-size: 10.5px; padding-right: 9px; color: var(--txt-1); }

/* data + footer value cells (dark text over the pastel fills) */
.wxs-dtable tbody td, .wxs-dtable tfoot td { color: #15202e; font-weight: 600; font-variant-numeric: tabular-nums; }
.wxs-dtable tfoot td { font-weight: 700; }
.wxs-dt-empty { background: #18202f; }
.wxs-dtable tfoot tr:first-child td, .wxs-dtable tfoot tr:first-child th { border-top: 2px solid rgba(120,150,200,.28); }
.wxs-dtable tfoot tr.wxs-dt-accum td, .wxs-dtable tfoot tr.wxs-dt-accum th { border-top: 1px dashed rgba(120,150,200,.2); }
/* faint divider at each month boundary in the dual (temperature) layout */
.wxs-dtable.is-dual tbody td:nth-child(even),
.wxs-dtable.is-dual tfoot td:nth-child(even) { border-left: 1px solid rgba(15,22,34,.18); }

/* monthly: emphasised Year column + trend marks + footnote */
.wxs-dt-yr { font-weight: 800 !important; }
.wxs-dtable--monthly tbody td.wxs-dt-yr, .wxs-dtable--monthly tfoot td.wxs-dt-yr,
.wxs-dtable--monthly thead th.wxs-dt-yr { border-left: 2px solid rgba(15,22,34,.22); }
.wxs-dtable--monthly thead th.wxs-dt-yr { border-left-color: rgba(120,150,200,.28); }
.wxs-dt-tr { font-size: 7px; vertical-align: middle; }
.wxs-dt-tr.up { color: #11713c; }
.wxs-dt-tr.down { color: #bd2c2c; }
.wxs-tbl-note { color: var(--txt-2); font-size: 11px; margin-top: 11px; }
.wxs-tbl-note:empty { display: none; }

.wxs-tbl-legend { display: flex; flex-wrap: wrap; align-items: center; margin: 16px 0 2px; }
.wxs-tbl-legend:empty { display: none; }
.wxs-lg-cap { color: var(--txt-2); font-weight: 700; margin-right: 12px; text-transform: uppercase; letter-spacing: .4px; font-size: 10.5px; }
.wxs-lg-cell { color: #15202e; font-weight: 700; padding: 3px 9px; font-size: 10px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.wxs-lg-cell:first-of-type { border-radius: 6px 0 0 6px; }
.wxs-lg-cell:last-of-type { border-radius: 0 6px 6px 0; }

/* zoom: let the wrapper break out past the content container, centred */
.wxs-tbl-scroll { box-sizing: border-box; }

/* desktop hover cross-highlight: light up the hovered day-row + month-column */
@media (hover: hover) and (pointer: fine) {
  .wxs-dtable tbody td, .wxs-dtable tfoot td,
  .wxs-dtable .wxs-dt-mon, .wxs-dtable .wxs-dt-day, .wxs-dtable .wxs-dt-sub { transition: filter .16s ease, color .16s ease; }
  .wxs-dtable .is-rowhi td, .wxs-dtable .is-rowhi th,
  .wxs-dtable td.is-colhi, .wxs-dtable th.is-colhi { filter: brightness(1.15) saturate(1.05); }
  .wxs-dtable .is-rowhi .wxs-dt-day, .wxs-dtable th.wxs-dt-mon.is-colhi { color: var(--accent); }
  .wxs-dtable tbody .is-rowhi td.is-colhi,
  .wxs-dtable tfoot .is-rowhi td.is-colhi { animation: wxs-cellpulse 1.3s ease-in-out infinite; position: relative; z-index: 1; }
}
@keyframes wxs-cellpulse {
  0%, 100% { box-shadow: inset 0 0 0 2px rgba(255,255,255,.28); }
  50%      { box-shadow: inset 0 0 0 2px rgba(255,255,255,.82); }
}
@media (max-width: 560px) { .wxs-dtable { font-size: 10px; } .wxs-dtable th, .wxs-dtable td { padding: 3px 5px; } }

/* ============================================================
   LITE MODE (perf) — auto-applied to low-end devices via config.js
   (old Android, low-RAM / onboard-GPU desktops). Strips the GPU-heavy
   backdrop-filter glass compositing that janks scrolling and swaps in
   opaque surfaces so the cards stay readable. iOS and capable desktops
   never receive `.wxs-lite`, so their appearance is completely untouched.
   ============================================================ */
html.wxs-lite {
  --glass-blur: 0px;
  --glass-bg:    #18243f;   /* opaque stand-ins for the frosted surfaces */
  --glass-bg-hi: #1f2f52;
  --glass-bg-lo: #131d34;
  --glass-shadow:    0 6px 16px rgba(0,0,0,.34);
  --glass-shadow-lo: 0 4px 10px rgba(0,0,0,.26);
}
/* the big win: no backdrop blur anywhere (the per-frame recomposite is the
   main scroll killer on old Android GPUs) */
html.wxs-lite *,
html.wxs-lite *::before,
html.wxs-lite *::after {
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}
/* drop the blurred background wash + the continuous decorative animations
   (Ken Burns pan, star twinkle, animated weather-icon parts) that repaint
   every frame; functional flashes/pulses (live dot, value roll) are kept */
html.wxs-lite .wxs-bg::after { filter: none !important; }
html.wxs-lite .wxs-banner.is-loaded .wxs-banner__img { animation: none !important; }
html.wxs-lite .wxs-cloudviz__stars::before { animation: none !important; }
html.wxs-lite [class^="wxi-"], html.wxs-lite [class*=" wxi-"] { animation: none !important; }
/* iOS: the weather-icon SVG animations re-rasterise on the GPU while scrolling (device heat) ->
   render the icons static on iOS; desktop/Android keep them. Class set in config.js. */
html.wxs-ios [class^="wxi-"], html.wxs-ios [class*=" wxi-"] { animation: none !important; }
/* Off-screen pause (all platforms): ui.js adds .wxs-apause to an icon wrapper / the banner when it
   scrolls out of view; play-state keeps the frame so motion resumes smoothly on return. */
.wxs-apause [class^="wxi-"], .wxs-apause [class*=" wxi-"] { animation-play-state: paused !important; }
.wxs-apause .wxs-banner__img { animation-play-state: paused !important; }

/* ============================================================
   MOBILE PERF (≤620px) — applies to EVERY phone, not just low-end.
   Even an iPhone Pro overheats while scrolling because (1) the STICKY header
   re-blurs the whole page every frame at 120Hz, and (2) decorative animations
   run non-stop (GPU busy even when idle/off-screen). On the mobile view we drop
   the remaining backdrop blur (opaque stand-ins) and stop those animations.
   The glass look survives via the translucent fills, borders, shadows, card
   sheen, and static icons. Desktop is untouched (this is width-gated).
   ============================================================ */
@media (max-width: 620px) {
  /* badges / live pill / drawer stay flat (blur not worth it on those) */
  .wxs-media-badge, .wxs-banner__live, .wxs-menu {
    -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
  }
  .wxs-media-badge   { background: rgba(9, 15, 28, 0.8); }
  .wxs-banner__live  { background: rgba(9, 15, 28, 0.82); }
  /* menu bar keeps a MINIMAL frosted glass (blur 3px vs the 10px elsewhere) over
     the translucent glass tone, so it matches the page instead of a dark opaque
     bar. Cheap on a thin header — much lighter than the big banner scroll-blur we
     removed — but it IS a per-frame reblur, so retest thermals on device. */
  .wxs-header__inner {
    background: var(--glass-bg);
    -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  }

  /* stop the HEAVY always-running decorative animations (continuous GPU, even off-screen):
     banner Ken-Burns pan + cloud-star twinkle. Functional micro-flashes (live dot, value
     roll) are left alone. NOTE: the animated weather-icon parts (sun rays / cloud drift /
     rain / snow / bolt …) are RE-ENABLED on mobile — tiny transform/opacity tweens on a
     small SVG. The wxs-lite perf mode still stops them on low-end devices (see above), and
     they respect prefers-reduced-motion. Retest thermals; revert this line if it's heavy. */
  .wxs-banner.is-loaded .wxs-banner__img { animation: none !important; will-change: auto; }
  .wxs-cloudviz__stars::before { animation: none !important; }

  /* Weather-icon parts stay animated on phones but THROTTLED: slow durations + stepped
     timing, so the animated property changes only a few times/second → the GPU (and the
     120Hz ProMotion display) idle between steps instead of compositing every frame. A big
     thermal cut vs the smooth desktop version while keeping a gentle sense of life. Tune
     the fps by nudging the steps() counts. (wxs-lite still stops them entirely on low-end
     devices; prefers-reduced-motion already opts out.) */
  /* .wxi-rays: dropped the stepped spin (looked jerky) — now a smooth opacity fade, see wxiRayFade block below */
  .wxi-cloud-shape { animation-duration: 12s;  animation-timing-function: steps(24);  }   /* ~2 fps drift */
  .wxi-star        { animation-duration: 6s;   animation-timing-function: steps(6);   }   /* ~1 fps twinkle */
  .wxi-fogline     { animation-duration: 8s;   animation-timing-function: steps(8);   }
  .wxi-wind        { animation-duration: 8s;   animation-timing-function: steps(8);   }
  .wxi-drop        { animation-duration: 1.5s; animation-timing-function: steps(9);   }   /* rain: coarse fall */
  .wxi-flake       { animation-duration: 3s;   animation-timing-function: steps(12);  }
  /* .wxi-bolt already uses steps(1) — inherently cheap, left as-is */

  /* the fixed blurred background wash → flat (one less GPU layer) */
  .wxs-bg::after { filter: none !important; }
}

/* Mobile sun-rays: a smooth opacity fade loop instead of the (jerky, ~3fps) stepped
   rotation. Opacity-only → cheap to composite, so it stays fluid on phones without the
   thermal cost of re-rasterising rotating rays every frame. Gated on no-preference so
   reduced-motion users still get stillness. Covers every day icon with visible rays. */
@keyframes wxiRayFade { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
@media (max-width: 620px) and (prefers-reduced-motion: no-preference) {
  .wxi-rays { animation: wxiRayFade 3.5s ease-in-out infinite; }
}

/* ============================================================
   LIGHT THEME — scoped overrides for colours that live OUTSIDE the
   token system (the ~28% of hardcoded darks) + elements that overlay
   the banner photo (which must stay light in BOTH themes because the
   photo is dark). Every rule is gated on :root[data-theme="light"], so
   the default dark theme never sees any of it. Kept together here so the
   whole light-theme surface is in one place.
   ============================================================ */

/* Header bar: uses the standard translucent --glass-bg + blur (same frosted
   level as the dark menu). The earlier near-opaque hack was only needed while
   light theme still showed the DARK night banner; with the daylight photo the
   translucent glass reads cleanly over the bright sky and over scrolled content,
   so no override here — the base .wxs-header__inner rule (var(--glass-bg)) wins. */

/* Stats dropdown was a hardcoded dark panel → light glass. */
:root[data-theme="light"] .wxs-dropdown {
  background: rgba(250, 252, 255, 0.97);
  border-color: var(--glass-brd-hi);
}

/* Native <select> OPTION lists on the stats subpages (NOAA year/month, Tables /
   History / Climate pickers, graph zoom-param) had a hardcoded dark #0c1426 option
   background that survived into light theme → the OPEN list rendered dark with
   near-invisible dark text. The closed control already flips via tokens; this makes
   the popped-open list light too. Scoped to light, so dark (incl. storm tracker) is
   untouched. */
:root[data-theme="light"] .wxs-sel option,
:root[data-theme="light"] .wxs-zoom-ctrl option { background: #f4f8fe; color: var(--txt-1); }

/* Elements sitting ON the banner photo keep LIGHT text in light mode too
   (dark token text would vanish on the dark photo). */
:root[data-theme="light"] .wxs-subbar,
:root[data-theme="light"] .wxs-sub-geo,
:root[data-theme="light"] .wxs-sub-date,
:root[data-theme="light"] .wxs-geo-x,
:root[data-theme="light"] .wxs-sub-update { color: #eaf1fb; }
:root[data-theme="light"] .wxs-sub-ic,
:root[data-theme="light"] .wxs-geo-i { color: #b9c8e0; }
/* both over-banner pills (update + geo) get the lighter fill; the geo coord
   values (<b>) must go light too so they read on the dark pill (their token
   colour is dark navy in light theme). */
:root[data-theme="light"] .wxs-sub-update,
:root[data-theme="light"] .wxs-sub-geo { background: rgba(10, 16, 30, 0.55); }
:root[data-theme="light"] .wxs-sub-geo b { color: #eaf1fb; }

/* Banner bottom finish, LIGHT theme (overrides the dark .wxs-banner::after): the
   stroke line is a DEEP navy at 4px (+2px vs dark — a mid-blue blended into the
   sea at the photo's edge) with a 1px light highlight riding above it so it reads
   on both the sea and the pale page; the name scrim goes stronger (white text on
   the bright daylight photo). Corner vignette kept lighter. */
:root[data-theme="light"] .wxs-banner::after {
  background:
    linear-gradient(to right, rgba(18,44,92,0), rgba(24,60,124,.96) 24%, rgba(28,72,150,1) 50%, rgba(24,60,124,.96) 76%, rgba(18,44,92,0)) center bottom / 100% 4px no-repeat,
    linear-gradient(to right, rgba(220,235,255,0), rgba(220,235,255,.75) 26%, rgba(235,245,255,.9) 50%, rgba(220,235,255,.75) 74%, rgba(220,235,255,0)) center calc(100% - 4px) / 100% 1px no-repeat,
    radial-gradient(144% 128% at 0% 118%, rgba(6,11,24,.96), rgba(6,11,24,.64) 32%, transparent 66%),
    radial-gradient(140% 130% at 50% 40%, transparent 62%, rgba(7,12,26,.16) 100%);
}

/* Storm-activity card: the calm-green status text + the light-yellow strike
   counters were near-invisible on light. Darken to readable ink (keep the
   green dot as the indicator); the alert state gets a strong dark amber. */
:root[data-theme="light"] .wxs-ltact__status--ok {
  color: var(--txt-1);
  background: rgba(31, 157, 104, 0.12);
  border-color: rgba(31, 157, 104, 0.34);
}
:root[data-theme="light"] .wxs-ltact__status--alert {
  color: #b4531b;
  background: rgba(224, 140, 40, 0.14);
  border-color: rgba(224, 140, 40, 0.42);
}
:root[data-theme="light"] .wxs-ltact__num,
:root[data-theme="light"] .wxs-ltact__bolt { color: #c9880f; }

/* Weather icons: the cloud/moon gradients are near-white (tuned for the dark
   ground) → they vanished on light cards. Deepen the gradient STOPS under
   light theme only (CSS stop-color overrides the SVG presentation attribute),
   so every icon that references them re-renders visibly. Dark is untouched. */
:root[data-theme="light"] #wxi-cloud      stop:first-child { stop-color: #b3c4dd; }
:root[data-theme="light"] #wxi-cloud      stop:last-child  { stop-color: #859bbb; }
:root[data-theme="light"] #wxi-cloud-mid  stop:first-child { stop-color: #9dafcb; }
:root[data-theme="light"] #wxi-cloud-mid  stop:last-child  { stop-color: #7085a5; }
:root[data-theme="light"] #wxi-cloud-dark stop:first-child { stop-color: #8091ad; }
:root[data-theme="light"] #wxi-cloud-dark stop:last-child  { stop-color: #5a6c8a; }
:root[data-theme="light"] #wxi-moon       stop:first-child { stop-color: #cdd9ee; }
:root[data-theme="light"] #wxi-moon       stop:last-child  { stop-color: #93a8ca; }
:root[data-theme="light"] #wxi-sun        stop:first-child { stop-color: #ffcf6a; }

/* Icon lift on light theme: the dark drop-shadow backdrops (invisible on the dark
   ground) read as heavy blobs on the pale cards → swap to a soft navy-tinted lift.
   Also pop the deep-blue card title icons to full opacity. Dark theme untouched. */
:root[data-theme="light"] .wxs-hero__icon { filter: drop-shadow(0 2px 5px rgba(40, 66, 110, 0.16)); }
:root[data-theme="light"] .wxs-moon       { filter: drop-shadow(0 3px 8px rgba(40, 66, 110, 0.18)); }
:root[data-theme="light"] .wxs-card__ic   { opacity: 1; }

/* Wind compass: the ring FILL is hardcoded dark navy, so the tick marks +
   N/E/S/W labels (which flip to dark tokens on light) went dark-on-dark and
   vanished. Light ring fill + firmer marks → the dark labels read on it. */
:root[data-theme="light"] .wxs-comp-ring  { fill: rgba(255, 255, 255, 0.55); stroke: var(--glass-brd-hi); }
:root[data-theme="light"] .wxs-comp-ring2 { stroke: rgba(60, 100, 170, 0.16); }
:root[data-theme="light"] .wxs-comp-mark  { stroke: var(--txt-2); opacity: 0.7; }

/* Hero temp/condition card: the radial temp-GLOW behind it bled out of the card
   as a warm smear on the pale ground — even dialled to .5 it read as a leak, so
   remove it entirely on light. Dark keeps its glow (the whole effect is the point
   there). The glow lives only in ::before, so display:none fully clears it. */
:root[data-theme="light"] .wxs-hero::before { display: none; }

/* ---- Colored data VALUES on light (2026-08-10) ----
   The fixed pastel hues read fine as chart strokes / on the dark ground but drop
   to ~1.5–3:1 as TEXT on the pale card. The JS-driven figures (gcard graph values,
   fire class, AQI, forecast hi-lo, the temp/wind ramps, chart tooltips) are deepened
   inside their own scripts (colorscale/dashboard/firewx/wx24h/wxgraphs/forecast .js);
   the few that live purely in CSS are deepened here. All land ≥4.5:1. Dark untouched. */
:root[data-theme="light"] .wxs-mm__hi,
:root[data-theme="light"] .wxs-mm__cell.hi b { color: #c0392b; }   /* max temp: salmon → deep red  (2.2 → 5.2:1) */
:root[data-theme="light"] .wxs-mm__lo,
:root[data-theme="light"] .wxs-mm__cell.lo b { color: #1f6fbf; }   /* min temp: sky   → deep blue (2.0 → 4.9:1) */
/* Menu-bar LIVE word: --good (#1f9d68) is only ~3.15:1 → deeper green. The :not()
   keeps the OFFLINE red (.is-offline, higher-priority state) winning. The pulsing
   dot stays --good — it's a shape, where 3:1 is fine. */
:root[data-theme="light"] .wxs-live:not(.is-offline) { color: #0f7a49; }
/* Rotating-line title was --txt-3 (faint ~2.2:1 territory pre-fix); lift to --txt-2
   so the Humidity/Wind/Rain label reads on the bright header glass. */
:root[data-theme="light"] .wxs-head-rl { color: var(--txt-2); }

/* Media preview pills (webcam label, satellite timestamp) were dark glass →
   swap to light glass with dark text. The lightning teaser badge stays dark
   (it sits over the intentionally-dark strike map). */
:root[data-theme="light"] .wxs-media-badge {
  background: rgba(250, 252, 255, 0.72);
  border-color: var(--glass-brd-hi);
}
:root[data-theme="light"] .wxs-media-badge--lt {
  background: rgba(9, 15, 28, 0.72);
  color: #ffd98a;
}

/* Graphs subpage (wxgraphs.php): the chart panels are a hardcoded solid dark
   navy (de-glassed for cleaner chart rendering) → light solid panel for light.
   The chart internals (axis/grid/min-max labels) darken via wxgraphs.js ink(). */
:root[data-theme="light"] .wxs-gp-card,
:root[data-theme="light"] .wxs-gp-focuschart { background: #f2f6fd; }
:root[data-theme="light"] .wxs-gp-card.is-expandable:hover { background: #e9f1fb; }

/* Detailed Tables subpage (wxtables.php): the sticky header row, the frozen
   day/corner/foot label cells, and the empty (missing-day) cells are hardcoded
   dark → light for light theme. Data cells keep their own heat-map colours
   (theme-independent) and their dark text stays readable on those pastels. */
:root[data-theme="light"] .wxs-dtable thead th,
:root[data-theme="light"] .wxs-dt-corner,
:root[data-theme="light"] .wxs-dt-day,
:root[data-theme="light"] .wxs-dt-foot { background: #e9eff8; }
:root[data-theme="light"] .wxs-dt-empty { background: #e6ecf5; }

/* ============================================================
   GRAPHITE overrides — hardcoded-navy STRUCTURAL surfaces the token remap
   can't reach (they use literal navy hex, exactly like the light overrides
   above). Scoped to the graphite variant ONLY, so navy + light keep their
   values. Same selectors as the light block, mapped to graphite charcoals.
   ============================================================ */
/* Stats (& other) nav submenu — base was rgba(19,29,53,.97) navy */
:root[data-theme="dark"][data-variant="graphite"] .wxs-dropdown {
  background: rgba(32, 32, 36, 0.98); border-color: var(--glass-brd-hi);
}
/* wxgraphs chart panels (opaque, de-glassed) — base was #141e39 navy */
:root[data-theme="dark"][data-variant="graphite"] .wxs-gp-card,
:root[data-theme="dark"][data-variant="graphite"] .wxs-gp-focuschart { background: #202024; }
:root[data-theme="dark"][data-variant="graphite"] .wxs-gp-card.is-expandable:hover { background: #26262b; }
/* wxtables structure: sticky header row + frozen label column/corner/foot + empty
   cells — base was #101a2c / #18202f navy (the value-coloured data cells untouched) */
:root[data-theme="dark"][data-variant="graphite"] .wxs-dtable thead th,
:root[data-theme="dark"][data-variant="graphite"] .wxs-dt-corner,
:root[data-theme="dark"][data-variant="graphite"] .wxs-dt-day,
:root[data-theme="dark"][data-variant="graphite"] .wxs-dt-foot { background: #1c1c20; }
:root[data-theme="dark"][data-variant="graphite"] .wxs-dt-empty { background: #202024; }
/* coords + update-time pills over the banner — base was rgba(10,16,30,.72) navy-tint */
:root[data-theme="dark"][data-variant="graphite"] .wxs-sub-update,
:root[data-theme="dark"][data-variant="graphite"] .wxs-sub-geo { background: rgba(24, 24, 28, 0.72); }
/* wind compass/rose — ring fill (rgba(10,18,38,.5)), inner ring stroke, and the
   needle's tail polygon (inline fill rgba(150,170,200,.4), overridden via CSS) were navy */
:root[data-theme="dark"][data-variant="graphite"] .wxs-comp-ring  { fill: rgba(16, 16, 19, 0.5); }
:root[data-theme="dark"][data-variant="graphite"] .wxs-comp-ring2 { stroke: rgba(150, 152, 160, 0.12); }
:root[data-theme="dark"][data-variant="graphite"] .wxs-comp-dom polygon { fill: rgba(160, 162, 170, 0.55); }

/* Cloud-base "sky tube" reads darker than intended on the light theme — lift
   the whole graphic (its own day/twilight/night sky stays, just brighter). */
:root[data-theme="light"] .wxs-cloudviz__sky { filter: brightness(1.13) saturate(1.03); }
/* Sky-tube upper-air TEMPS: JS colours these with WXS.tempCss() in day/night — but on
   light theme that ramp is DEEP/dark and reads poorly on the (still-dark) sky. Force
   the flat white (#eef4ff, the twilight look) on light, overriding the inline colour
   and dropping the day-state dimming filter. Dark theme keeps its colour-coding. */
:root[data-theme="light"] .wxs-cloudviz__lvl-t { color: #eef4ff !important; filter: none !important; }

/* Analog thermometer: the glass tube FILL is a dark navy (rgba(8,14,30,.55)) tuned
   for the dark ground — it read as a heavy dark bar on the light card. Swap to a
   pale frosted fill so the thermometer brightens up on light. Dark is untouched. */
:root[data-theme="light"] .wxs-th-tube { fill: rgba(232,240,251,.72); }

/* ============================================================
   LIGHT-THEME FLAT VALUE INK + refinements (2026-08-17)
   The light theme's --txt-0 is now the friendly slate #33425c (tokens.css), so all
   token-based titles/values are consistent. This block drops the gradient colour on
   the INLINE-coloured live values -> flat ink (var --flat-ink) + a few light-only
   tweaks. Scoped to [data-theme=light]; dark/navy keeps every gradient. KEPT in light:
   min/max .hi/.lo cells, 1h/24h change indicators, graph LINES.
   ============================================================ */
:root[data-theme="light"] { --flat-ink: #33425c; }
:root[data-theme="light"] #wxs-hero-temp { color: var(--flat-ink) !important; text-shadow: none !important; }
:root[data-theme="light"] #wxs-head-main,
:root[data-theme="light"] #wxs-wind-spd,
:root[data-theme="light"] #wxs-wind-gust,
:root[data-theme="light"] #wxs-wind-dir,
:root[data-theme="light"] #wxs-hum,
:root[data-theme="light"] #wxs-baro,
:root[data-theme="light"] .wxs-firewx__cat,
:root[data-theme="light"] #wxs-aqi-cat,
:root[data-theme="light"] .fc-hi,
:root[data-theme="light"] .fc-lo,
:root[data-theme="light"] #wxs-rain-today,
:root[data-theme="light"] #wxs-rain-storm,
:root[data-theme="light"] #wxs-rain-daysmonth,
:root[data-theme="light"] .wxs-gcard__val,
:root[data-theme="light"] [id^="wxs-g-"][id$="-val"],
:root[data-theme="light"] .wxs-gp-val,
:root[data-theme="light"] .wxs-gp-val span { color: var(--flat-ink) !important; }
/* the two remaining aggressive-black leftovers the --txt-0 token can't reach: the comfort word
   (inline #16203a from dashboard.js) + the mobile drawer theme/language toggles (were pure #000) */
:root[data-theme="light"] #wxs-heatword { color: var(--flat-ink) !important; }
:root[data-theme="light"] #wxs-menu-theme,
:root[data-theme="light"] #wxs-menu-lang { color: var(--flat-ink); }
/* storm-total row is .wxs-kv--accent (accent-blue label + value, storm-only) - flatten the LABEL
   too so the whole row reads neutral (its value is already flattened above). */
:root[data-theme="light"] .wxs-kv--accent i { color: var(--txt-2) !important; }
/* brighten the analogue thermometer mercury - its temperature gradient reads dim on the pale
   frosted tube in light theme. */
:root[data-theme="light"] .wxs-th-merc { filter: saturate(1.45) brightness(1.07) drop-shadow(0 0 3px var(--temp-glow)); }
/* bolder min/max labels in the humidity + barometer mini-cards */
:root[data-theme="light"] .wxs-hbx__mm .wxs-kv i { font-weight: 700 !important; }
/* drop the thin dark outline (4-way drop-shadow) on the weather icons (current + forecast) */
:root[data-theme="light"] .wxi { filter: none !important; }
/* Firefox-only, light theme: Firefox jags the sponsor CARD's rounded corners because of the
   translucent color-mix BORDER + backdrop-filter + sharp inset highlight (Chrome renders fine). Draw
   the outline with an INSET box-shadow ring instead of a border (box-shadow follows border-radius
   cleanly in FF), on a solid opaque fill with no backdrop-filter / inset highlight. Only the
   card-sponsor stations (Palaiochori / Kalamonas / Agios) render .wxs-spon__card. */
:root.wxs-ff[data-theme="light"] .wxs-spon__card {
  -webkit-backdrop-filter: none; backdrop-filter: none;
  background: #fbf6ee;
  border-color: transparent;
  box-shadow: 0 4px 14px rgba(40,30,15,.16),
              inset 0 0 0 1px color-mix(in srgb, var(--spon-accent) 44%, #cbb894);
}

/* ============ settings gear + popover (theme + language) — mini settings menu ============
   A single cog button in the header opens a mini menu: theme (icon-only row) + language.
   On mobile the same menu renders inline in the burger drawer, collapsed behind a cogwheel
   "Ρυθμίσεις" row. Solid panel like the Stats submenu (no blur), per-theme coloured. */
.wxs-lang { display: none; }   /* language now lives inside the gear settings menu */
.wxs-gear { position: relative; }
.wxs-gear__btn { display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 32px; border-radius: 9px; cursor: pointer; padding: 0;
  background: var(--glass-bg-lo); border: 1px solid var(--glass-brd); color: var(--txt-1);
  transition: background .15s, color .15s, border-color .15s; }
.wxs-gear__btn:hover { color: var(--txt-0); border-color: var(--glass-brd-hi); }
.wxs-gear__btn[aria-expanded="true"] { color: var(--accent-2); border-color: var(--glass-brd-hi); background: var(--accent-soft); }
.wxs-gear__btn .wxs-mi { width: 17px; height: 17px; }
.wxs-gear__pop { position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  min-width: 194px; padding: 8px; border-radius: 14px;
  /* solid panel like the Stats submenu — no blur, per-theme high-opacity fill */
  background: rgba(19, 29, 53, 0.97); border: 1px solid var(--glass-brd);
  box-shadow: var(--glass-shadow), var(--inset-hi);
  animation: wxsGearIn .16s ease; }
:root[data-theme="light"] .wxs-gear__pop { background: rgba(250, 252, 255, 0.97); border-color: var(--glass-brd-hi); }
:root[data-theme="dark"][data-variant="graphite"] .wxs-gear__pop { background: rgba(32, 32, 36, 0.98); border-color: var(--glass-brd-hi); }
@keyframes wxsGearIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.wxs-set__sec { padding: 3px; }
.wxs-set__sec + .wxs-set__sec { margin-top: 5px; padding-top: 8px; border-top: 1px solid var(--glass-brd); }
.wxs-set__lbl { margin: 2px 7px 5px; font-size: 10px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--txt-3); }
.wxs-set__opt { display: flex; align-items: center; gap: 9px; width: 100%; padding: 8px 9px; border: 0; border-radius: 9px;
  background: transparent; color: var(--txt-1); cursor: pointer; font: inherit; font-size: 13px; font-weight: 600; text-align: left;
  transition: background .13s, color .13s; }
.wxs-set__opt:hover { background: var(--glass-brd); color: var(--txt-0); }
.wxs-set__opt.is-active { color: var(--accent-2); }
.wxs-set__ic { display: inline-grid; place-items: center; width: 20px; flex: none; color: inherit; }
.wxs-set__ic .wxs-mi { width: 16px; height: 16px; }
.wxs-set__ic--lang { font-size: 10px; font-weight: 800; letter-spacing: .01em; }
.wxs-set__nm { flex: 1; }
.wxs-set__ck { width: 16px; height: 16px; flex: none; color: var(--accent-2); opacity: 0; }
.wxs-set__opt.is-active .wxs-set__ck { opacity: 1; }
/* theme options as an icon-only row (names dropped → mini icons; tooltip carries the name) */
.wxs-set__icons { display: flex; gap: 4px; padding: 2px 3px; }
.wxs-set__ico { flex: 1; display: inline-grid; place-items: center; height: 34px; padding: 0;
  border: 0; border-radius: 9px; background: transparent; color: var(--txt-2); cursor: pointer;
  transition: background .13s, color .13s; }
.wxs-set__ico:hover { background: var(--glass-brd); color: var(--txt-0); }
.wxs-set__ico.is-active { background: var(--accent-soft); color: var(--accent-2); }
.wxs-set__ico .wxs-mi { width: 17px; height: 17px; }
/* mobile burger drawer: settings menu inline (no gear), full-width below the meta */
@media (max-width: 1024px) {
  .wxs-menu-extra { flex-wrap: wrap; }
  .wxs-menu-ctrls { flex: 1 0 100%; flex-direction: column; align-items: stretch; gap: 2px; margin-top: 4px; }
  .wxs-menu-ctrls .wxs-set__opt { padding: 10px; font-size: 14px; }
  .wxs-menu-ctrls .wxs-set__lbl { margin-left: 4px; }
  .wxs-menu-group--set .wxs-dropdown { padding-left: 6px; }
  .wxs-menu-group--set .wxs-set__sec { padding: 2px 0; }
  .wxs-menu-group--set .wxs-set__sec + .wxs-set__sec { margin-top: 4px; padding-top: 6px; }
  .wxs-menu-group--set .wxs-set__lbl { margin-left: 8px; }
}

/* ===== Section-headline display face — Syne (chosen 2026-09-11 via Font Lab) =====
   The light-blue headlines (.wxs-shead__t): dashboard section labels, subpage
   page-headers, media-box heads. Only face/weight/tracking change — colour and
   size stay as the original, so navy / graphite / light all remain intact.
   Syne loads via the Google Fonts <link> in each page's <head> (with Inter).

   ---- BACKUP · how to revert to the previous (Inter) headline ----
   The ORIGINAL rules are still present above (the ".wxs-shead" block:
   .wxs-shead__t = font-weight 800, letter-spacing 1.4px, NO font-family, i.e.
   Inter via var(--font); .wxs-shead--page .wxs-shead__t = letter-spacing .8px).
   To go back to Inter: delete THIS block and drop "&family=Syne:wght@600..800"
   from the Google Fonts <link> in each page <head> — the originals then resume. */
.wxs-shead__t {
  font-family: 'Syne', var(--font);
  font-weight: 710;
  letter-spacing: 0.5px;
  text-transform: uppercase;
}
.wxs-shead--page .wxs-shead__t { letter-spacing: 0.5px; }   /* match the section tracking (overrides the .8px page default) */

/* The forecast headline drops its leading "Αυτόματη" / "Automatic" on MOBILE to
   save width — on the dashboard forecast section head AND the forecast subpage
   header. The prefix is its own .wxs-fc-auto span; the margin gives the word-gap
   so hiding it leaves no stray leading space. */
.wxs-fc-auto { margin-right: .3em; }
@media (max-width: 620px) { .wxs-fc-auto { display: none; } }

/* footer social icons (Facebook + YouTube) — links injected by ui.js buildFooter().
   Mobile: pushed to the far bottom of the footer (order) below the status line.
   Desktop (≥768px): floated fixed to the bottom-right corner of the viewport. */
.wxs-foot__social { display: flex; justify-content: center; gap: 10px; margin: 12px 0 2px; order: 10; }
.wxs-foot__soc { display: inline-grid; place-items: center; width: 28px; height: 28px; border-radius: 8px;
  color: var(--txt-3); background: var(--glass-brd); transition: color .14s, background .14s, transform .14s; }
.wxs-foot__soc svg { width: 15px; height: 15px; }
.wxs-foot__soc:hover { transform: translateY(-1px); }
.wxs-foot__soc--fb:hover { color: #fff; background: #1877f2; }
.wxs-foot__soc--yt:hover { color: #fff; background: #ff0000; }
@media (min-width: 1025px) {
  .wxs-foot__social { position: fixed; right: 18px; bottom: 16px; margin: 0; z-index: 40; }
}

/* misc card: external-data source note + info "!" (top-right) + native-sensor LED.
   Flags that solar/UV/AQI/PM are Open-Meteo/IQAir, not native station readings. */
.wxs-misc-src { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; text-transform: none; letter-spacing: 0; }
.wxs-misc-src__txt { font-size: 9.5px; font-weight: 600; color: var(--txt-3); white-space: nowrap; }
.wxs-info {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 15px; height: 15px; padding: 0; border-radius: 50%; border: 1px solid var(--glass-brd);
  background: transparent; color: var(--txt-2); font-size: 10px; font-weight: 800; line-height: 1;
  font-family: Georgia, "Times New Roman", serif; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: color .14s, border-color .14s;
}
.wxs-info:hover, .wxs-info:focus-visible { color: var(--txt-0); border-color: var(--accent); outline: none; }
.wxs-tip-pop {
  position: fixed; z-index: 3000; max-width: 260px; padding: 10px 12px; border-radius: 10px;
  font-size: 11px; font-weight: 500; line-height: 1.45; color: var(--txt-1); text-align: left;
  background: #141e39; border: 1px solid var(--glass-brd-hi); box-shadow: 0 12px 30px rgba(0,0,0,.42);
  opacity: 0; visibility: hidden; transform: translateY(-4px); pointer-events: none;
  transition: opacity .16s ease, transform .16s ease, visibility .16s;
}
.wxs-tip-pop.is-on { opacity: 1; visibility: visible; transform: translateY(0); }
:root[data-theme="light"] .wxs-tip-pop { background: #ffffff; color: #2a3852; border-color: rgba(70,110,175,.28); box-shadow: 0 12px 30px rgba(40,70,120,.2); }
:root[data-theme="dark"][data-variant="graphite"] .wxs-tip-pop { background: #202024; }
/* native-sensor marker: a solar-sensor station shows a small yellow LED beside the Solar label
   (revealed when ui.js adds html.wxs-solar-native for a features.solar station). */
.wxs-labrow { display: inline-flex; align-items: center; gap: 5px; }
.wxs-native-dot { display: none; width: 7px; height: 7px; border-radius: 50%; flex: none; background: #ffcf3f; box-shadow: 0 0 6px rgba(255,207,63,.75); }
.wxs-solar-native .wxs-native-dot { display: inline-block; }

/* ============================================================
   NETWORK STATION SWITCHER (left slide-out) + MOBILE HOME FAB (ui.js buildNetMenu / buildHomeFab).
   All-token-themed → follows dark / light / graphite automatically. Fixed-layer budget: FAB 45,
   scrim 999, panel 1000, tab 1001 — below the header's popovers (3000) and the storm-map
   fullscreen (9000), above page content and the header (50).
   ============================================================ */
.wxs-net__scrim {
  position: fixed; inset: 0; z-index: 999;
  background: rgba(4, 8, 18, .6);   /* darken the page behind the panel (no blur -- a plain dim, per request) */
  opacity: 0; visibility: hidden; transition: opacity .28s ease, visibility .28s ease;
}
.wxs-net.is-open .wxs-net__scrim { opacity: 1; visibility: visible; }

.wxs-net__panel {
  position: fixed; top: 0; left: 0; height: 100%;
  width: min(320px, 86vw); z-index: 1000;
  display: flex; flex-direction: column;
  background-color: var(--bg-0); background-image: linear-gradient(var(--glass-bg-hi), var(--glass-bg-hi)); border-right: 0;   /* opaque: glass tint over the page base (no blur, no bleed-through) */
  transform: translateX(-100%); transition: transform .28s cubic-bezier(.4, 0, .2, 1);
}
.wxs-net.is-open .wxs-net__panel { transform: translateX(0); border-right: 1px solid var(--glass-brd-hi); box-shadow: 8px 0 28px rgba(0, 0, 0, .4); }

/* the pull-tab is a VIEWPORT-FIXED element (NOT a child of the transformed panel), so it stays
   rock-steady during mobile scroll (fixed % is relative to the viewport, not the panel's dynamic
   height); on open it translates right by the panel width to ride the panel's edge. */
.wxs-net__tab {
  position: fixed; left: 0; z-index: 1001; top: 50%; top: 50svh; transform: translateY(-50%) translateZ(0); -webkit-backface-visibility: hidden; backface-visibility: hidden;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  width: 34px; padding: 13px 0; margin: 0; cursor: pointer;
  background: var(--glass-bg-hi); border: 1px solid var(--glass-brd-hi); border-left: 0;
  border-radius: 0 var(--r-md) var(--r-md) 0; color: var(--accent-2);
  box-shadow: 4px 0 14px rgba(0, 0, 0, .28);
  /* no backdrop-filter here on purpose: as a position:fixed element it would re-blur the whole
     scrolling page every frame (iOS scroll heat) for no real gain -- it sits over the plain page
     background at the left edge, not over content; the --glass-bg-hi tint reads the same. */
  transition: transform .28s cubic-bezier(.4, 0, .2, 1), background .15s ease, color .15s ease;
}
.wxs-net.is-open .wxs-net__tab { transform: translateY(-50%) translateX(min(320px, 86vw)); }
.wxs-net__tab:hover { background: var(--glass-bg); color: var(--accent); }
.wxs-net__tab .wxs-mi { width: 20px; height: 20px; }
.wxs-net__chev { width: 9px; height: 14px; color: var(--txt-2); transition: transform .28s ease; }
.wxs-net.is-open .wxs-net__chev { transform: rotate(180deg); }

.wxs-net__head { display: flex; align-items: center; gap: 10px; padding: 15px 14px 12px; border-bottom: 1px solid var(--glass-brd); }
.wxs-net__logo { height: 26px; width: auto; flex: none; display: block; filter: drop-shadow(0 2px 5px rgba(0,0,0,.35)); }
.wxs-net__title { flex: 1; min-width: 0; font-family: var(--font); font-weight: 700; font-size: 15px; color: var(--txt-0); letter-spacing: .2px; }
.wxs-net__close { flex: none; display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 8px; border: 0; cursor: pointer; background: transparent; color: var(--txt-2); }
.wxs-net__close:hover { background: var(--accent-soft); color: var(--txt-0); }
.wxs-net__close .wxs-mi { width: 18px; height: 18px; }

.wxs-net__list { flex: 1; overflow-y: auto; padding: 10px 10px 18px; -webkit-overflow-scrolling: touch; }

.wxs-net__home { display: flex; align-items: center; gap: 9px; padding: 10px 12px; border-radius: var(--r-sm); color: var(--txt-0); text-decoration: none; font-weight: 600; font-size: 14px; background: var(--accent-soft); border: 1px solid var(--glass-brd); transition: border-color .13s ease, color .13s ease; }
.wxs-net__home:hover { border-color: var(--glass-brd-hi); color: var(--accent-2); }
.wxs-net__home .wxs-mi { width: 19px; height: 19px; color: var(--accent-2); flex: none; }
.wxs-net__hometxt { flex: none; white-space: nowrap; }
.wxs-net__homelogo { height: 17px; width: auto; margin-left: auto; flex: none; display: block; }
:root[data-theme="light"] .wxs-net__homelogo { filter: brightness(.28); }   /* white wordmark -> darkened so it reads on the pale panel */
.wxs-net__sep { height: 1px; margin: 10px 4px; background: var(--glass-brd); }
.wxs-net__map { margin-top: 7px; font-size: 13px; }   /* wxmap link: longer label than the home pill -> a touch smaller to stay on one line (no logo) */

.wxs-net__row { display: flex; align-items: center; gap: 8px; padding: 8px 12px; border-radius: var(--r-sm); text-decoration: none; color: var(--txt-1); transition: background .13s ease; }
.wxs-net__row:hover { background: var(--glass-bg-lo); color: var(--txt-0); }
.wxs-net__led { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--txt-3); transition: background .2s ease, box-shadow .2s ease; }
.wxs-net__led.is-on { background: var(--good); box-shadow: 0 0 6px rgba(70, 209, 138, .6); }
.wxs-net__led.is-off { background: var(--bad); box-shadow: 0 0 5px rgba(255, 107, 107, .5); }
.wxs-net__nm { font-size: 13.5px; font-weight: 600; color: var(--txt-0); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wxs-net__ar { font-size: 10.5px; color: var(--txt-3); white-space: nowrap; flex: none; }
.wxs-net__temp { margin-left: auto; flex: none; font-size: 13px; font-weight: 700; color: var(--txt-1); font-variant-numeric: tabular-nums; white-space: nowrap; }
.wxs-net__row.is-here { background: var(--accent-soft); cursor: default; }
.wxs-net__row.is-here .wxs-net__nm { color: var(--accent-2); }
.wxs-net__here { flex: none; font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: #fff; background: var(--accent); border-radius: 6px; padding: 2px 6px; }

/* Home FAB pill -- TABLET only (621-1024). On mobile the home link is the subbar mini-pill
   (see the .wxs-subbar rules in the <=620 block); on desktop it is the centered subbar pill. */
.wxs-homefab { display: none; }
.wxs-homefab__txt { display: none; }
@media (min-width: 621px) and (max-width: 1024px) {
  .wxs-homefab {
    position: fixed; right: 14px; bottom: 14px; z-index: 45;
    width: 46px; height: 46px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--glass-bg-hi); border: 1px solid var(--glass-brd-hi); color: var(--accent-2);
    box-shadow: var(--glass-shadow); text-decoration: none;
    -webkit-backdrop-filter: blur(var(--glass-blur)); backdrop-filter: blur(var(--glass-blur));
    transition: transform .15s ease;
  }
  .wxs-homefab:active { transform: scale(.94); }
  .wxs-homefab .wxs-mi { width: 22px; height: 22px; }
}

/* tablet only: the home FAB is a wider bottom-CENTER pill showing its label (mobile = subbar pill) */
@media (min-width: 621px) and (max-width: 1024px) {
  .wxs-homefab {
    left: 50%; right: auto; bottom: 18px; transform: translateX(-50%);
    width: auto; height: auto; padding: 11px 22px; gap: 9px; border-radius: 999px;
  }
  .wxs-homefab:active { transform: translateX(-50%) scale(.96); }
  .wxs-homefab .wxs-mi { width: 20px; height: 20px; }
  .wxs-homefab__txt { display: inline; font-weight: 600; font-size: 14px; letter-spacing: .2px; white-space: nowrap; }
  /* the centered pill would sit on top of the centered social icons -> send them to the footer bottom-RIGHT */
  .wxs-foot__social { align-self: flex-end; }
}

@media (prefers-reduced-motion: reduce) {
  .wxs-net__panel, .wxs-net__scrim, .wxs-net__chev, .wxs-net__tab { transition: none; }
}
