/* skysounding — deliberately close to the AMDAR Archive's instrument-panel look,
   so a meteorologist moving between the two sites is not relearning an
   interface. Cyan rather than amber is the one deliberate difference: this is a
   different data source with different caveats, and the colour is a constant
   reminder of that. */
:root{
  --slate-900:#0b0f14; --slate-800:#111821; --slate-700:#1a2330; --slate-600:#243040;
  --line:#26303c; --line-strong:#33414f;
  --cyan:#22d3ee; --cyan-bright:#67e8f9; --cyan-dim:#0e7490;
  --text:#c8d3de; --text-dim:#8b99a8; --text-faint:#657585; --text-bright:#eef4fa;
  --warn:#ffb000; --bad:#ff5470; --good:#7ee081;
  --font-ui:'Segoe UI',system-ui,-apple-system,sans-serif;
  --font-mono:'Cascadia Mono','Consolas',ui-monospace,monospace;
  --topbar-h:56px;
  --shadow:0 12px 34px rgba(0,0,0,.55);
}
*{box-sizing:border-box}
/* The `hidden` attribute only sets display:none at the UA level, so ANY later
   display rule silently overrides it. #status and #snd both set display:flex
   and both stayed visible when hidden. One global line prevents that whole
   class of bug rather than patching each panel as it appears. */
[hidden]{display:none!important}
html,body{margin:0;height:100%;background:var(--slate-900);color:var(--text);
  font-family:var(--font-ui);overflow:hidden}

/* ---- top bar ------------------------------------------------------------ */
#topbar{position:absolute;inset:0 0 auto 0;height:var(--topbar-h);z-index:1200;
  display:flex;align-items:center;gap:14px;padding:0 14px;
  background:linear-gradient(180deg,var(--slate-800),var(--slate-900));
  border-bottom:1px solid var(--line-strong);
  overflow-x:auto;overflow-y:hidden;scrollbar-width:thin}
#topbar>*{flex:0 0 auto}
.brand{display:flex;align-items:center;gap:9px;font-size:16px;letter-spacing:.3px;
  color:var(--text-bright);font-weight:600}
.brand .sub{color:var(--cyan)}
.brand svg{width:18px;height:18px;color:var(--cyan)}
.about-tab{margin-left:2px;padding:4px 12px;background:rgba(34,211,238,.10);
  border:1px solid var(--cyan-dim);border-radius:5px;cursor:pointer;
  font-family:var(--font-ui);font-size:12px;font-weight:600;color:var(--cyan-bright)}
.about-tab:hover{background:rgba(34,211,238,.22)}

.picker{display:flex;align-items:center;gap:9px;margin-left:6px}
.fld{display:flex;flex-direction:column;gap:2px}
.fld span{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.7px;
  text-transform:uppercase;color:var(--text-faint)}
.fld input,.fld select{font-family:var(--font-mono);font-size:12px;color:var(--text-bright);
  background:var(--slate-700);border:1px solid var(--line-strong);border-radius:6px;
  padding:5px 7px}
.fld input:focus-visible,.fld select:focus-visible{outline:2px solid var(--cyan);outline-offset:1px}

.btn{font-family:var(--font-ui);font-size:12px;color:var(--text);
  background:var(--slate-700);border:1px solid var(--line-strong);border-radius:7px;
  padding:8px 13px;cursor:pointer;display:inline-flex;align-items:center;gap:7px;
  transition:background .15s,border-color .15s,color .15s}
.btn:hover{background:var(--slate-600);border-color:var(--cyan-dim)}
.btn:focus-visible{outline:2px solid var(--cyan-bright);outline-offset:2px}
.btn.primary{background:var(--cyan);color:#04222a;border-color:var(--cyan-dim);font-weight:700}
.btn.primary:hover{background:var(--cyan-bright)}
.btn.primary:disabled{opacity:.5;cursor:default}
.btn.ghost{background:none;border:none;color:var(--text-faint);font-size:20px;
  line-height:1;padding:2px 7px}
.btn.ghost:hover{color:var(--cyan-bright);background:none}

.readout{display:flex;align-items:center;gap:16px;font-family:var(--font-mono)}
.readout .item{display:flex;flex-direction:column;gap:2px}
.readout .lbl{font-size:9.5px;letter-spacing:.7px;text-transform:uppercase;color:var(--text-faint)}
.readout .val{font-size:12.5px;color:var(--text-bright)}

/* ---- map ---------------------------------------------------------------- */
#map{position:absolute;inset:var(--topbar-h) 0 0 0;background:#0d1117}
.leaflet-container{background:#0d1117}
.leaflet-control-attribution{background:rgba(11,15,20,.82)!important;
  color:var(--text-faint)!important;font-size:10px!important}
.leaflet-control-attribution a{color:var(--text-dim)!important}

/* ---- panels ------------------------------------------------------------- */
.panel{position:fixed;z-index:1100;background:var(--slate-800);
  border:1px solid var(--line-strong);border-radius:10px;padding:13px 15px;
  box-shadow:var(--shadow)}
.panel h3{margin:0 0 9px;font-family:var(--font-mono);font-size:10px;letter-spacing:.8px;
  text-transform:uppercase;color:var(--text-faint);font-weight:600}

#filters{left:12px;top:calc(var(--topbar-h) + 12px);width:212px}
.rrow{display:flex;align-items:center;gap:8px;padding:4px 0;font-size:12.5px;cursor:pointer}
.rrow input{accent-color:var(--cyan);cursor:pointer}
.rrow .n{margin-left:auto;font-family:var(--font-mono);font-size:11px;color:var(--text-dim)}
.rrow.zero{opacity:.42}
.rrow .gapmark{color:var(--bad);font-family:var(--font-mono);font-size:10px}
.chk{display:flex;align-items:center;gap:8px;margin-top:10px;padding-top:10px;
  border-top:1px solid var(--line);font-size:12.5px;cursor:pointer;color:var(--good)}
.chk input{accent-color:var(--good);cursor:pointer}

/* ---- status ------------------------------------------------------------- */
#status{left:50%;transform:translateX(-50%);top:calc(var(--topbar-h) + 12px);
  width:min(430px,calc(100vw - 32px));display:flex;align-items:center;gap:13px}
.spinner{width:20px;height:20px;flex:0 0 auto;border-radius:50%;
  border:2px solid var(--line-strong);border-top-color:var(--cyan);
  animation:spin .9s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.status-head{font-size:13px;color:var(--text-bright);font-weight:600}
.status-sub{font-family:var(--font-mono);font-size:11px;color:var(--text-dim);margin-top:3px}
#status.err .spinner{animation:none;border-color:var(--bad);border-top-color:var(--bad)}
#status.err .status-head{color:var(--bad)}

#hint{position:fixed;left:50%;transform:translateX(-50%);
  top:calc(var(--topbar-h) + 12px);z-index:1090;
  background:var(--slate-800);border:1px solid var(--line-strong);border-radius:8px;
  padding:8px 14px;font-size:12.5px;color:var(--text-dim);box-shadow:var(--shadow)}
#hint b{color:var(--cyan-bright)}

/* ---- sounding drawer ---------------------------------------------------- */
/* Toggled by a class, not the `hidden` attribute: display:flex here would
   override [hidden] and leave an empty drawer sitting over the map. */
/* Wider than it was: a Skew-T at 560px is cramped, and the tab strip for a busy
   site ran off the edge. min-width keeps it usable on a narrow laptop; the map
   still has the majority of the screen. */
#snd{position:fixed;right:0;top:var(--topbar-h);bottom:0;
  width:clamp(420px,42vw,720px);
  z-index:1300;background:var(--slate-800);border-left:1px solid var(--line-strong);
  display:none;flex-direction:column;box-shadow:-14px 0 40px rgba(0,0,0,.5)}
#snd.open{display:flex}
.snd-head{display:flex;align-items:flex-start;justify-content:space-between;
  gap:10px;padding:12px 14px;border-bottom:1px solid var(--line)}
.snd-title{font-family:var(--font-mono);font-size:15px;color:var(--cyan-bright);font-weight:600}
.snd-meta{font-family:var(--font-mono);font-size:11px;color:var(--text-dim);margin-top:3px}
.snd-body{flex:1;min-height:0;overflow-y:auto;padding:12px;background:#0e141b}
.snd-body img{width:100%;height:auto;display:block;border-radius:6px;
  cursor:zoom-in}
.snd-note{font-size:12px;color:var(--text-dim);padding:9px 2px 2px;line-height:1.5}
.snd-note b{color:var(--text-bright)}

/* ---- about -------------------------------------------------------------- */
#about{left:50%;transform:translateX(-50%);top:calc(var(--topbar-h) + 16px);
  width:min(640px,calc(100vw - 32px));
  max-height:calc(100vh - var(--topbar-h) - 46px);overflow-y:auto;padding:20px 24px 22px}
#about .x{position:absolute;top:7px;right:10px}
#about h2{margin:0 0 11px;font-size:18px;color:var(--cyan-bright);padding-right:22px}
#about h3{margin:17px 0 7px;font-family:var(--font-mono);font-size:11px;letter-spacing:.8px;
  text-transform:uppercase;color:var(--cyan);font-weight:600}
#about p{margin:0 0 10px;line-height:1.6;font-size:13.5px}
#about b{color:var(--text-bright)}
#about a{color:var(--cyan-bright)}
#about .caveat{font-size:12.5px;color:var(--text-dim);
  border-left:2px solid var(--line-strong);padding-left:11px}
table.cmp{border-collapse:collapse;width:100%;font-family:var(--font-mono);
  font-size:12px;margin:4px 0 12px}
table.cmp th{text-align:right;color:var(--text-faint);font-weight:500;
  padding:0 0 6px;font-size:10px;letter-spacing:.5px;text-transform:uppercase}
table.cmp th:first-child{text-align:left}
table.cmp td{padding:4px 0;border-top:1px solid var(--line)}
table.cmp td:not(:first-child){text-align:right}
table.cmp .ok{color:var(--text-faint)}
table.cmp .gap{color:var(--bad);font-weight:700}

@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
@media (max-width:820px){
  #snd{width:100vw;left:0}
  #filters{width:170px}
}

/* ---- airport markers ----------------------------------------------------- */
/* One marker per airport. A count replaces the smear of overlapping dots a busy
   field used to draw — Las Vegas alone had 120 profiles in one cycle. */
.apt{width:11px;height:11px;border-radius:50%;background:var(--cyan);
  opacity:.75;box-shadow:0 0 0 1px #0b0f14}
.apt.wet{background:var(--good);opacity:.95}
.apt.multi{width:22px;height:22px;border-radius:50%;opacity:.95;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--font-mono);font-size:10.5px;font-weight:700;color:#04222a;
  box-shadow:0 0 0 1px #0b0f14,0 2px 6px rgba(0,0,0,.5)}
.leaflet-marker-icon:hover .apt{filter:brightness(1.25)}

/* ---- sounding tabs ------------------------------------------------------- */
/* Tabs WRAP rather than scroll sideways. A site with twenty profiles pushed the
   last of them past the panel edge, where they looked cut off rather than
   scrollable. Wrapping shows them all; the max-height caps it at about four rows
   and scrolls beyond that, so the plot is never squeezed off screen. */
.snd-tabs{display:flex;flex-wrap:wrap;gap:6px;padding:9px 12px;
  max-height:118px;overflow-y:auto;
  border-bottom:1px solid var(--line);background:var(--slate-800);
  scrollbar-width:thin}
.snd-tabs .tab{flex:0 0 auto;font-family:var(--font-mono);font-size:11px;
  background:var(--slate-700);color:var(--text-dim);
  border:1px solid var(--line-strong);border-radius:6px;padding:5px 9px;cursor:pointer}
.snd-tabs .tab:hover{border-color:var(--cyan-dim);color:var(--text)}
.snd-tabs .tab.on{background:var(--cyan);color:#04222a;border-color:var(--cyan-dim);
  font-weight:700}
.snd-tabs .tab.wet .tt{color:var(--good)}
.snd-tabs .tab.on .tt{color:#04222a}
.snd-tabs .tab .tt{color:var(--text-faint);margin-left:2px}
.snd-wait{padding:26px 4px;text-align:center;font-size:12.5px;color:var(--text-dim)}
.snd-wait.err{color:var(--bad)}
.panel h3 .hdr-sub{float:right;font-size:9px;color:var(--text-faint);
  letter-spacing:.4px;text-transform:none;font-weight:400}

/* ---- overlay key --------------------------------------------------------- */
/* The colours in the plot legend are small; repeat them as text where a tail
   and time can be read beside each swatch. */
.ov-key{display:flex;flex-wrap:wrap;gap:9px 16px;padding:11px 3px 2px}
.ov-item{display:flex;align-items:center;gap:7px;font-family:var(--font-mono);
  font-size:11.5px;color:var(--text-dim)}
.ov-item i{width:13px;height:3px;border-radius:2px;display:inline-block}
.tab-hint{flex:0 0 auto;align-self:center;padding-left:6px;
  font-family:var(--font-mono);font-size:10px;color:var(--text-faint);
  white-space:nowrap}

/* Basemap in two layers. The land is darkened to match the interface; the
   boundaries-and-places overlay stays near full strength so national borders and
   place names remain legible instead of being darkened into invisibility. */
/* Brightness ONLY — no contrast or saturation change. Esri’s dark canvas already
   separates land from ocean by a small margin, and a contrast boost crushes both
   toward black, erasing every coastline. Scaling brightness alone preserves the
   ratio, so land stays visibly lighter than water. */
.base-tiles{filter:brightness(0.7)}
.ref-tiles{filter:brightness(1.35) contrast(1.2)}

/* ---- model comparison ---------------------------------------------------- */
.snd-model{display:flex;align-items:center;gap:7px;padding:8px 12px;
  border-bottom:1px solid var(--line);background:var(--slate-800);flex-wrap:wrap}
.snd-model .ml{font-family:var(--font-mono);font-size:10px;letter-spacing:.7px;
  text-transform:uppercase;color:var(--text-faint);margin-right:2px}
.mbtn{font-family:var(--font-mono);font-size:11px;background:var(--slate-700);
  color:var(--text-dim);border:1px solid var(--line-strong);border-radius:6px;
  padding:4px 10px;cursor:pointer}
.mbtn:hover{border-color:var(--cyan-dim);color:var(--text)}
.mbtn.on{background:var(--cyan);color:#04222a;border-color:var(--cyan-dim);font-weight:700}
.mnote{font-family:var(--font-mono);font-size:10px;color:var(--text-faint);
  margin-left:auto;white-space:nowrap}
.mbtn:disabled{opacity:.35;cursor:default;border-color:var(--line)}
.mbtn:disabled:hover{color:var(--text-dim);border-color:var(--line)}

/* ---- full-screen sounding ------------------------------------------------ */
/* The side panel is fine for a glance; reading a Skew-T properly needs the whole
   window. Click the plot to open it here. */
#zoom{position:fixed;inset:0;z-index:2000;background:rgba(6,9,13,.95);
  display:none;flex-direction:column}
#zoom.open{display:flex}
.zoom-head{display:flex;align-items:center;gap:18px;padding:10px 16px;
  border-bottom:1px solid var(--line-strong);flex:0 0 auto;
  /* Solid, not transparent: the overlay sits over the map and the header text
     was unreadable against country labels showing through. */
  background:var(--slate-800)}
.zoom-title{font-family:var(--font-mono);font-size:14px;color:var(--cyan-bright);
  font-weight:600}
.zoom-meta{font-family:var(--font-mono);font-size:11px;color:var(--text-dim)}
.zoom-body{flex:1;min-height:0;overflow:auto;display:flex;
  align-items:flex-start;justify-content:center;padding:14px}
.zoom-body img{max-width:none;height:calc(100vh - 110px);width:auto;
  border-radius:6px;cursor:zoom-out}
.zoom-body.fit img{height:auto;max-width:100%;width:auto}
.zoom-hint{font-family:var(--font-mono);font-size:10.5px;color:var(--text-faint);
  margin-left:auto}
.zoom-close{margin-left:14px}

/* A profile whose humidity readings swing wildly between adjacent levels. Marked
   rather than smoothed: an obviously bad trace can be discounted, an invented
   smooth one cannot. */
.snd-note .warn{color:var(--warn);font-weight:600}
.snd-tabs .tab.noisy .tt{color:var(--warn)}
.snd-tabs .tab.noisy::after{content:"!";margin-left:4px;color:var(--warn);font-weight:700}
.snd-tabs .tab.on.noisy::after{color:#04222a}

/* Plot / Data view switch, sharing the model row. Kept visually distinct from
   the model buttons with a divider: choosing a model and choosing how to read
   the profile are different decisions. */
.vsep{width:1px;height:20px;background:var(--line-strong);margin:0 4px}
.mnote{margin-left:auto}
.lev-wrap{padding:2px 0 0}
.lev-meta{font-family:var(--font-mono);font-size:11px;color:var(--text-dim);
  padding:2px 2px 9px;line-height:1.5}
.lev-meta b{color:var(--text-bright)}
table.lev{border-collapse:collapse;width:100%;font-family:var(--font-mono);font-size:11.5px}
table.lev th{position:sticky;top:0;background:#0e141b;text-align:right;
  color:var(--text-faint);font-weight:500;padding:4px 6px 5px;font-size:10px;
  letter-spacing:.5px;border-bottom:1px solid var(--line-strong)}
table.lev td{padding:2px 6px;text-align:right;border-bottom:1px solid #1a2330;
  color:var(--text)}
table.lev tr:hover td{background:#16202a}
table.lev .c-p{color:var(--text-bright)}
table.lev .c-t{color:#ff6b5e}
table.lev .c-td{color:var(--good)}
table.lev .c-na{color:var(--text-faint)}
.lev-h{font-family:var(--font-mono);font-size:10px;letter-spacing:.8px;
  text-transform:uppercase;color:var(--cyan);margin:14px 0 5px;font-weight:600}
.lev-actions{display:flex;gap:7px;padding:10px 0 2px}
