/* ==========================================================================
   Weather — hazard dashboard (admin only)

   Two pieces: a summary bar across the top, and a row of vertical panels that
   behave as a single-open accordion. Collapsed panels are narrow strips with
   nothing but a white icon; opening one closes the rest.

   Status colour is the whole point of the panel, so the palette is chosen for
   legibility rather than to match Mello's usual pastels: every status carries
   white text at >= 4.5:1 in both modes. That constraint is what keeps the
   yellow deep (gold, not lemon) and separates it from the amber warning.
   ========================================================================== */

:root {
  --wx-strip: 66px;          /* collapsed panel width */
  --wx-bar-h: 66px;          /* bottom icon+title bar; matches --wx-strip */
  --wx-open-ms: 380ms;
  --wx-ease: cubic-bezier(0.22, 0.61, 0.36, 1);

  /* LIGHT */
  --wx-ok:        #1f7a4a;
  --wx-attention: #9a7b0a;
  --wx-warning:   #c05621;
  --wx-critical:  #b02525;
  --wx-unknown:   #5c626b;

  /* Alert-badge palette. Deliberately brighter and more saturated than the
     panel fills above: the badge sits ON one of those fills, so it has to
     escape it. Shared between light and dark rather than split, because it has
     to out-shout both sets. The glyph is near-black on all three (>=5.8:1). */
  --wx-alert-ok:        #34d17f;
  --wx-alert-attention: #f5c518;
  --wx-alert-warning:   #f5891f;
  --wx-alert-critical:  #ef3b36;
  --wx-alert-unknown:   #9aa3ad;
  --wx-alert-ink:       #14181d;

  --wx-badge: 48px;
}

body[data-mode="dark"] {
  --wx-ok:        #14603a;
  --wx-attention: #7a610a;
  --wx-warning:   #97421a;
  --wx-critical:  #8c1d1d;
  --wx-unknown:   #3a3f47;
}

/* Per-status tokens, resolved once on the panel so everything inside can just
   use --wx-c without repeating the four-way switch. */
.wx-panel[data-status="ok"]        { --wx-c: var(--wx-ok); }
.wx-panel[data-status="attention"] { --wx-c: var(--wx-attention); }
.wx-panel[data-status="warning"]   { --wx-c: var(--wx-warning); }
.wx-panel[data-status="critical"]  { --wx-c: var(--wx-critical); }
.wx-panel[data-status="unknown"]   { --wx-c: var(--wx-unknown); }

/* ===== Summary bar (placeholder) ========================================= */

.wx-summary {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: 88px;
  padding: 0.9rem 1.15rem;
  margin-bottom: 0.9rem;
  border-radius: 0;
  /* --color-surface, NOT --surface-1. The latter is declared on :root as
     `var(--panel-bg)`, and custom properties substitute on the element that
     DECLARES them — so it computes against :root's light value and inherits
     down frozen, staying light in dark mode. base.css:56 warns about exactly
     this. --color-surface is redeclared on body[data-mode="dark"], so it
     tracks the mode, and being opaque it is also the flat look wanted here. */
  background: var(--color-surface);
  border: 1px solid var(--border-color);
}

.wx-summary-dot {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--wx-c, var(--wx-unknown));
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--wx-c, var(--wx-unknown)) 22%, transparent);
}

.wx-summary-main { min-width: 0; flex: 1 1 auto; }

.wx-summary-title {
  font-family: var(--font-header);
  font-size: 1.05rem;
  line-height: 1.2;
}

.wx-summary-sub {
  margin-top: 0.2rem;
  font-size: 0.85rem;
  opacity: 0.7;
}

.wx-summary-tag {
  flex: 0 0 auto;
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.28rem 0.55rem;
  border-radius: 0;
  border: 1px dashed var(--border-color);
  opacity: 0.6;
}

/* ===== Panel accordion =================================================== */

.wx-board {
  display: flex;
  gap: 8px;
  /* Deliberately shallow — these are summaries, not articles. ~60% of the
     original board height; the open panel scrolls if a source is chatty. */
  height: clamp(255px, 37vh, 385px);
  align-items: stretch;
}

.wx-panel {
  position: relative;
  /* Collapsed strips share a fixed basis; the open one takes the slack via
     flex-grow. Animating grow (not width) keeps the row's total width exact,
     so nothing reflows sideways mid-transition. */
  flex: 0 1 var(--wx-strip);
  min-width: 0;
  overflow: hidden;
  color: #fff;
  background: var(--wx-c, var(--wx-unknown));
  border-radius: 0;
  transition:
    flex-grow var(--wx-open-ms) var(--wx-ease),
    background-color 260ms ease;
}

.wx-panel.is-open { flex-grow: 1; }

/* The trigger covers the whole strip while collapsed, so anywhere on a narrow
   panel opens it. Once open it retreats to the header band and hands the rest
   of the panel back to the body, whose links need to be clickable.

   Neither the icon nor the title lives inside the trigger: both anchor to the
   panel's bottom edge, and the trigger (being positioned) would become their
   containing block and drag them along as it resizes. */
.wx-panel-trigger {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: block;
  padding: 1.05rem 1.15rem;
  border: 0;
  background: transparent;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color 180ms ease;
}

.wx-panel:not(.is-open) .wx-panel-trigger:hover {
  background: rgba(255, 255, 255, 0.10);
}

.wx-panel-trigger:focus-visible {
  outline: 2px solid #fff;
  outline-offset: -4px;
}

.wx-panel.is-open .wx-panel-trigger {
  inset: auto 0 0 0;
  height: var(--wx-bar-h);
  cursor: default;
}

/* Bottom-anchored so a row of collapsed strips reads as a line of icons along
   the foot of the board. pointer-events:none keeps the collapsed strip fully
   clickable through it. */
.wx-panel-icon {
  position: absolute;
  left: 0;
  bottom: 0;
  z-index: 3;
  width: var(--wx-strip);
  height: var(--wx-strip);
  display: grid;
  place-items: center;
  font-size: 2.1rem;
  line-height: 1;
  color: #fff;
  pointer-events: none;
}

/* Sits in the bottom bar to the right of the icon, centred against it. Like
   the icon it is a sibling of the trigger, so it stays put as the trigger
   resizes. pointer-events:none keeps the whole strip clickable. */
.wx-panel-heading {
  position: absolute;
  left: var(--wx-strip);
  right: 1.15rem;
  bottom: 0;
  z-index: 3;
  height: var(--wx-bar-h);
  display: flex;
  align-items: center;
  min-width: 0;
  opacity: 0;
  transform: translateX(-8px);
  white-space: nowrap;
  pointer-events: none;
  transition: opacity 200ms ease, transform 200ms ease;
}

.wx-panel.is-open .wx-panel-heading {
  opacity: 1;
  transform: none;
  transition-delay: 120ms;
}

.wx-panel-title {
  display: block;
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 1.5rem;
  line-height: 1.2;
}

/* Upcoming marker. A panel can be green because the hazard has not started yet
   (see aggregate.py rule 5), and that must not look identical to a genuinely
   quiet panel — so the badge carries the hazard's TRUE colour.

   Square, not round, to match everything else here; fixed size, so opening a
   panel moves nothing. It stays pinned to the top-left corner in both states,
   which on desktop is the empty gutter above the icon. */
.wx-panel-alert {
  position: absolute;
  top: 10px;
  left: calc((var(--wx-strip) - var(--wx-badge)) / 2);
  z-index: 4;
  width: var(--wx-badge);
  height: var(--wx-badge);
  display: grid;
  place-items: center;
  background: var(--wx-alert, var(--wx-alert-unknown));
  color: var(--wx-alert-ink);
  font-size: 1.5rem;
  line-height: 1;
  border-radius: 0;
  pointer-events: none;
}

/* ===== Panel body ======================================================== */

.wx-panel-body {
  position: absolute;
  /* Sits ABOVE the icon+title bar rather than below a header. Left padding
     matches the title's indent so copy lines up with it. */
  inset: 0 0 var(--wx-bar-h) 0;
  z-index: 1;
  padding: 1.05rem 1.15rem 0.4rem var(--wx-strip);
  overflow-y: auto;
  overscroll-behavior: contain;
  opacity: 0;
  pointer-events: none;
  transition: opacity 180ms ease;
}

.wx-panel.is-open .wx-panel-body {
  opacity: 1;
  pointer-events: auto;
  transition-delay: 160ms;
}

.wx-panel-blurb {
  font-size: 0.85rem;
  opacity: 0.82;
  margin-bottom: 0.9rem;
  max-width: 60ch;
}

.wx-signal {
  padding: 0.7rem 0.85rem;
  margin-bottom: 0.55rem;
  border-radius: 0;
  background: rgba(255, 255, 255, 0.13);
  border-left: 3px solid rgba(255, 255, 255, 0.55);
  max-width: 72ch;
}

.wx-signal-head {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.wx-signal-title {
  font-weight: 600;
  font-size: 0.95rem;
}

.wx-signal-badge {
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.14rem 0.4rem;
  border-radius: 0;
  background: rgba(255, 255, 255, 0.2);
}

/* Not yet in force: dimmed, because the board is about now. */
.wx-signal.is-upcoming {
  opacity: 0.82;
  border-left-style: dashed;
}

/* Status marker on every signal headline, in the signal's TRUE colour.

   On all signals rather than just upcoming ones: a panel can hold several
   findings at different severities — a live warning, an all-clear from another
   source, something building for Friday — and scanning colour is quicker than
   reading each badge. Round rather than square because it sits inline in a run
   of text, where a square reads as a bullet glitch.

   Solid, deliberately. It carries state, not urgency; the panel fill and the
   corner badge already do the shouting. */
.wx-signal-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  margin-right: 0.4rem;
  vertical-align: baseline;
  background: var(--wx-alert, var(--wx-alert-unknown));
}

.wx-signal-when {
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.14rem 0.4rem;
  border-radius: 0;
  border: 1px dashed rgba(255, 255, 255, 0.55);
}

.wx-signal-detail {
  margin-top: 0.3rem;
  font-size: 0.85rem;
  line-height: 1.45;
  opacity: 0.9;
}

.wx-signal-meta {
  margin-top: 0.4rem;
  font-size: 0.72rem;
  opacity: 0.75;
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.wx-signal-meta a { color: #fff; text-decoration: underline; }

.wx-panel-empty {
  font-size: 0.88rem;
  opacity: 0.8;
  padding: 0.6rem 0;
}

.wx-status { padding: 1rem 0; opacity: 0.75; }

/* ===== Narrow screens: the row becomes a stack ============================
   Seven 66px strips plus an open panel does not fit a phone, so below this
   breakpoint the accordion runs vertically. flex-grow can't animate against an
   auto height, so the stacked form transitions max-height instead. */

@media (max-width: 760px) {
  .wx-board {
    flex-direction: column;
    height: auto;
    gap: 6px;
  }

  .wx-panel {
    flex: 0 0 auto;
    max-height: 58px;
    transition: max-height var(--wx-open-ms) var(--wx-ease), background-color 260ms ease;
  }

  .wx-panel.is-open { max-height: 42vh; }

  /* THE BAR SITS AT THE TOP HERE, not the bottom as on desktop.
     Vertical space is the scarce resource on a phone: a bottom-anchored bar
     leaves the top of an open panel empty and squeezes the body into a narrow
     middle band. Anchored to the top it reads as an ordinary accordion header
     and the body simply flows beneath it. */
  .wx-panel-trigger { padding: 0.7rem 1rem; }
  .wx-panel.is-open .wx-panel-trigger { inset: 0 0 auto 0; height: 58px; }

  .wx-panel-icon {
    top: 0;
    bottom: auto;
    width: 58px;
    height: 58px;
    font-size: 1.65rem;
  }

  /* The title shows while COLLAPSED too. A vertical 66px strip had no room for
     it, but a full-width row does, and a list of names is far quicker to scan
     than a column of unlabelled icons. */
  .wx-panel-heading {
    top: 0;
    bottom: auto;
    left: 58px;
    /* Clears the 36px alert badge (right: 0.75rem) with a gap, so a long title
       ellipses before it reaches the badge rather than sliding under it. */
    right: 3.9rem;
    height: 58px;
    opacity: 1;
    transform: none;
  }

  .wx-panel-title {
    font-size: 1.25rem;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* Far end of the bar: the icon owns the top-left here. Smaller than desktop
     so it fits the 58px bar with room to breathe, and the heading reserves
     space for it via `right`. */
  .wx-panel-alert {
    --wx-badge: 36px;
    left: auto;
    right: 0.75rem;
    top: 11px;
    font-size: 1.15rem;
    transform: none;
  }

  /* Static flow, so the bar's space is reserved with padding. Only the top
     needs reserving now, and the body runs the full width rather than being
     indented past an icon that is no longer beside it. */
  .wx-panel-body {
    position: static;
    inset: auto;
    padding: 58px 1rem 1rem 1rem;
    max-height: calc(42vh - 8px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .wx-panel,
  .wx-panel-heading,
  .wx-panel-trigger,
  .wx-panel-body { transition-duration: 1ms; }
}
