/* ==========================================================================
   css/map.css — the map tile. Owned by js/map.js (CONTRACTS.md §2).
   --------------------------------------------------------------------------
   Roots: hw-maptile, hw-callout(s), hw-mapchips, hw-maplegend,
   hw-edgearrow, plus the existing hw-map__* family. Colour from app.css
   tokens only, both themes. Shared primitives (hw-tile*, hw-chipbtn, hw-btn*)
   are shell's; this file only places them.

   The map's HEIGHT is not set here: app.css sizes #map per breakpoint
   (--map-h), and the stage wrapper simply wraps it.
   ========================================================================== */

/* ---- tile skeleton -------------------------------------------------------
   A one-column grid whose template changes with the mode:
     Full                 head / stage / legend
     Simple, desktop      one cell: stage, with callouts + pill laid over it
     Simple, strip/phone  stage / callouts (+ pill in flow on desktop strip)
   Templates list only the areas that mode shows, so a hidden mount never
   leaves a row gap behind. */

.hw-maptile {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "stage";
  row-gap: var(--tile-gap, 12px);
  position: relative;
}

#map-head     { grid-area: head; min-width: 0; }
#map-legend   { grid-area: legend; min-width: 0; }
#map-callouts { grid-area: callouts; min-width: 0; }

/* Height is shell's --map-h token (app.css §04.10, per layout and breakpoint);
   the map fills the stage. Agreed with shell 2026-09-13. */
.hw-maptile__stage {
  grid-area: stage;
  position: relative;
  min-width: 0;
  height: var(--map-h);
  border-radius: var(--r-inner, 12px);
  overflow: hidden;
  /* Leaflet panes climb to z-index 1000; keep them inside the stage so the
     callouts and the edge arrow can sit on top with small numbers. */
  isolation: isolate;
}

#map { height: 100%; }

/* Leaflet's stylesheet paints every link in the container #0078A8, which
   measured 4.01:1 on the fallback surface. Fallback and popup links take
   the accent token instead (attribution links are styled by app.css). */
#map .hw-map__fallback a,
#map .leaflet-popup-content a { color: var(--accent); }

html[data-mode="full"] .hw-maptile { grid-template-areas: "head" "stage" "legend"; }
html[data-mode="simple"] .hw-maptile { grid-template-areas: "stage" "callouts"; }

#map-head:empty, #map-legend:empty, #map-callouts:empty { display: none; }

/* ---- Full: header chips --------------------------------------------------- */

.hw-maptile__head { flex-wrap: wrap; row-gap: var(--s-2); }

.hw-mapchips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
}
.hw-mapchips__fit { margin-inline-start: var(--s-2); }
.hw-mapchips .hw-chipbtn:disabled { opacity: 0.55; cursor: not-allowed; }

/* ---- Full: legend chip row BELOW the map --------------------------------- */

.hw-maplegend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin: 0;
  padding: 0 var(--s-1);
  list-style: none;
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--text-dim);
}
.hw-maplegend__item { display: inline-flex; align-items: center; gap: 6px; }
.hw-maplegend__swatch { flex: none; inline-size: 14px; block-size: 10px; border-radius: 3px; }
.hw-maplegend__swatch--fill { background: var(--hw-swatch); }
.hw-maplegend__swatch--ring { border: 2.5px solid var(--hw-swatch); border-radius: 50%; block-size: 12px; inline-size: 12px; }
.hw-maplegend__swatch--line { block-size: 3px; border-radius: 2px; background: var(--hw-swatch); }
.hw-maplegend__swatch--dash { block-size: 0; border-radius: 0; border-top: 3px dashed var(--hw-swatch); }
.hw-maplegend__swatch--cone {
  border: 1.5px dashed var(--hw-swatch);
  background: color-mix(in srgb, var(--hw-swatch) 14%, transparent);
}

/* ---- Full: the guidance card (a Leaflet control, top left) --------------- */

#map .hw-map__status {
  max-inline-size: min(300px, 55vw);
  margin: var(--s-3) 0 0 var(--s-3);
  padding: 8px 10px 10px;
  border-radius: var(--r-inner, 12px);
  background: var(--tile, var(--surface));
  box-shadow: var(--shadow-3);
  color: var(--text);
  /* It sits ON the map it describes, so it recedes until it is wanted: the
     reader's own hover or focus brings it back to full strength. */
  opacity: 0.86;
}
#map .hw-map__status:hover,
#map .hw-map__status:focus-within { opacity: 1; }
/* Reduced to its title row — the state a reader picks when the card is in the
   way — it fades further, but never past legible. */
#map .hw-map__status--min { opacity: 0.5; }
#map .hw-map__status--min .hw-map__status-content { display: none; }

.hw-map__status-head {
  display: flex;
  align-items: center;
  gap: 8px;
  min-inline-size: 0;
}
#map .hw-map__status-title {
  margin: 0;
  min-inline-size: 0;
  font: 800 var(--fs-xs) / 1.35 var(--font-display, var(--font-ui));
  color: var(--text);
}
.hw-map__status-toggle {
  flex: none;
  margin-inline-start: auto;
  display: inline-grid;
  place-items: center;
  inline-size: 22px;
  block-size: 22px;
  padding: 0;
  border: 0;
  border-radius: var(--r-pill, 999px);
  background: transparent;
  color: var(--text-faint);
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
}
.hw-map__status-toggle:hover { color: var(--text); background: var(--tile-2, var(--surface-2)); }
.hw-map__status-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* The glyph points at what pressing it does: open card, press to close. */
.hw-map__status--min .hw-map__status-toggle > [aria-hidden] { transform: rotate(-90deg); }

.hw-map__status-list {
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 2px;
  font-size: var(--fs-2xs);
  line-height: 1.4;
}
.hw-map__status-list:empty { display: none; }
.hw-map__status-item {
  display: flex;
  gap: 6px;
  align-items: baseline;
  min-inline-size: 0;
}
.hw-map__status-name { flex: none; font-weight: 700; color: var(--text); }
.hw-map__status-meta {
  min-inline-size: 0;
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.hw-map__status-item--more { color: var(--text-faint); }
.hw-map__status-extra {
  margin: 6px 0 0;
  font-size: var(--fs-2xs);
  line-height: 1.45;
  color: var(--text-dim);
  /* Three lines on screen; the whole sentence is in the live region and in
     the card's tooltip. Unclamped it measured 300 x 200 px over the map. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
}
.hw-map__status-extra:empty { display: none; }

/* Below 768 px the card comes OFF the map (js/map.js re-homes it into the tile
   rather than into a Leaflet control) and takes a row of its own under the
   legend. Measured at 390x844 in Full: on a 342x388 stage the 212x86 card
   covered the top three guidance chips outright, and the isolation notice in
   the opposite corner overlapped the card as well. A phone's stage has room
   for the map or for two cards on top of it, not both. Full strength and full
   text here, because off the map there is nothing for it to hide. */
.hw-map__status--below {
  box-sizing: border-box;
  inline-size: 100%;
  max-inline-size: none;
  margin: 0;
  padding: 10px 12px;
  border-radius: var(--r-inner, 12px);
  background: var(--tile-2, var(--surface-2));
  box-shadow: none;
  color: var(--text);
  opacity: 1;
}
.hw-map__status--below.hw-map__status--min { opacity: 1; }
.hw-map__status--below .hw-map__status-extra {
  display: block;
  -webkit-line-clamp: none;
  line-clamp: none;
  overflow: visible;
}

/* ---- the isolation notice (Full, top right) ------------------------------ */

#map .hw-map__isolate {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  margin: var(--s-3) var(--s-3) 0 0;
}

/* ---- Simple: callout cards ----------------------------------------------- */

.hw-callouts { margin: 0; padding: 0; list-style: none; }

.hw-callout {
  box-sizing: border-box;
  inline-size: 220px;
  padding: 12px 14px;
  border-radius: var(--r-lg);
  border-inline-start: 4px solid var(--hw-callout-rail, var(--border-strong));
  background: var(--tile, var(--surface));
  box-shadow: var(--shadow-3);
  color: var(--text);
}
.hw-callout__title {
  margin: 0;
  font: 800 var(--fs-sm) / 1.3 var(--font-display, var(--font-ui));
  color: var(--text);
}
.hw-callout__body {
  margin: 2px 0 0;
  font-size: var(--fs-2xs);
  line-height: 1.4;
  color: var(--text-dim);
}
.hw-callout__glyph { font-weight: 800; color: var(--text); }

/* ---- Simple, desktop: the cards laid over the stage -----------------------
   #map-callouts shares the stage's grid cell. The layer itself ignores the
   pointer so the map stays draggable between cards; the cards opt back in. */

@media (min-width: 768px) {
  html[data-mode="simple"] .hw-maptile:not(.hw-maptile--strip) { grid-template-areas: "stage"; }

  html[data-mode="simple"] .hw-maptile:not(.hw-maptile--strip) #map-callouts {
    grid-area: stage;
    position: relative;
    z-index: 2;
    pointer-events: none;
  }
  html[data-mode="simple"] .hw-maptile:not(.hw-maptile--strip) .hw-callout { pointer-events: auto; }

  html[data-mode="simple"] .hw-maptile:not(.hw-maptile--strip) .hw-callout { position: absolute; }
  .hw-maptile:not(.hw-maptile--strip) .hw-callout--tl { top: var(--s-4); left: var(--s-4); }
  .hw-maptile:not(.hw-maptile--strip) .hw-callout--tr { top: var(--s-4); right: var(--s-4); }
  /* Lifted clear of the attribution line along the bottom edge. */
  .hw-maptile:not(.hw-maptile--strip) .hw-callout--bl { bottom: 26px; left: var(--s-4); }
  .hw-maptile:not(.hw-maptile--strip) .hw-callout--br { bottom: 26px; right: var(--s-4); }

  /* Strip fallback on desktop (the overlap validator chose it): the cards go
     under the map, in flow. */
  html[data-mode="simple"] .hw-maptile--strip { grid-template-areas: "stage" "callouts"; }
}

/* ---- Simple: the swipe strip (phones, and the desktop fallback) ---------- */

.hw-maptile--strip .hw-callouts,
.hw-callouts {
  /* Default (phone-first) is the strip; the desktop overlay above positions
     the cards absolutely, which takes them out of this flex row. */
  display: flex;
  gap: 10px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
  padding-block-end: 4px;
}
.hw-maptile--strip .hw-callout,
.hw-callouts .hw-callout {
  flex: 0 0 min(78%, 260px);
  scroll-snap-align: start;
}
@media (max-width: 767.98px) {
  .hw-callout { background: var(--tile-2, var(--surface-2)); box-shadow: none; }
}
.hw-maptile--strip .hw-callout { background: var(--tile-2, var(--surface-2)); box-shadow: none; }

/* ---- the far-storm edge arrow -------------------------------------------- */

.hw-edgearrow {
  position: absolute;
  z-index: 3;
  transform: translate(-50%, -50%);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-block-size: 36px;
  padding: 6px 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
  background: var(--tile, var(--surface));
  box-shadow: var(--shadow-3);
  color: var(--text);
  font: 700 var(--fs-xs) / 1.2 var(--font-display, var(--font-ui));
  white-space: nowrap;
  cursor: pointer;
}
.hw-edgearrow__glyph { display: inline-block; color: var(--accent); }
.hw-edgearrow__text { font-variant-numeric: tabular-nums; }
.hw-edgearrow:hover { background: var(--tile-2, var(--surface-2)); }
.hw-edgearrow:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---- basemap and map-internal overrides ---------------------------------- */

/* app.css darkens the tile pane for the old CARTO basemap. Esri's Dark Gray
   Canvas is already dark; dimming it further sank the coastlines. */
#map.hw-map__root--dark .leaflet-tile-pane { filter: none; }

/* Simple's guidance veil: the model name chips share the label pane, so they
   are hidden by class rather than with the guidance pane (see map.js). */
#map.hw-map__root--veil .hw-map__guidance-chip-wrap { display: none; }

/* ---- touch: 44 px targets ------------------------------------------------- */

@media (pointer: coarse) {
  .hw-map__status-toggle { inline-size: 44px; block-size: 44px; }
  .hw-mapchips .hw-chipbtn { min-block-size: 44px; }
  .hw-edgearrow { min-block-size: 44px; }
  #map .hw-map__isolate .hw-chipbtn { min-block-size: 44px; }
}

/* ---- motion --------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  #map .hw-map__status { transition: opacity var(--dur-2) var(--ease-out); }
  .hw-map__status-toggle > [aria-hidden] { transition: transform var(--dur-2) var(--ease-out); }
  .hw-edgearrow { transition: background-color var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out); }
}
html[data-motion="off"] #map .hw-map__status,
html[data-motion="off"] .hw-map__status-toggle > [aria-hidden],
html[data-motion="off"] .hw-edgearrow { transition: none; }
