/* Theming contract: every colour/font here is var(--token, fallback) -
   the token names match maptools-uk's src/styles/global.css exactly
   (--bg, --card, --text, --text-muted, --primary, --success, --border,
   --shadow-lg, --radius-*, --spacing-*, --font-sans). When this widget
   is embedded inside a maptools-uk page, those tokens are already
   defined on an ancestor element and cascade in automatically - no
   override needed. The fallback value after the comma is what you see
   in THIS standalone demo (no maptools CSS loaded) and matches
   maptools' own light-theme default, so the demo already previews the
   "native" look. See CLAUDE.md's "Embedding contract" section - do not
   hardcode a colour or font anywhere in this file without a var(). */

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }

#climate-map-widget {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 320px;
  overflow: hidden;
  font-family: var(--font-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif);
  color: var(--text, #0f172a);
  background: var(--bg, #ffffff);
  container-type: inline-size;
  container-name: cm-widget;
}

#map { position: absolute; inset: 0; }
#filter-canvas { position: absolute; inset: 0; pointer-events: none; z-index: 5; }

#dev-banner {
  position: absolute; top: 0; left: 0; right: 0; z-index: 10;
  background: var(--warning, #f59e0b); color: #ffffff; text-align: center;
  font-size: 12px; font-weight: 600; padding: 4px 8px; letter-spacing: 0.02em;
}

#panel {
  position: absolute; top: 40px; left: 12px; z-index: 10;
  background: var(--card, #ffffff); color: var(--text, #0f172a);
  border: 1px solid var(--border, rgba(0,0,0,0.1));
  border-radius: var(--radius-lg, 10px); padding: var(--spacing-lg, 14px);
  width: 300px; max-width: calc(100% - 24px); /* was 280px - bumped so the date-range row's two month selects (min-width 78px each, see below) plus day inputs don't overflow */
  box-shadow: var(--shadow-lg, 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -2px rgba(0,0,0,0.05));
  font-size: 13px;
}
#panel .section { margin-top: var(--spacing-md, 12px); }
#panel label {
  display: block; font-weight: 600; margin-bottom: var(--spacing-xs, 6px);
  color: var(--text-muted, #6b7280); font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em;
}
#panel .row { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
#panel .hint { color: var(--text-muted, #6b7280); font-size: 11px; margin-top: var(--spacing-sm, 8px); }
#panel select, #panel input[type=number] {
  background: var(--bg-secondary, #f4f7fb); color: var(--text, #0f172a);
  border: 1px solid var(--border, rgba(0,0,0,0.1)); border-radius: var(--radius-sm, 6px);
  padding: 5px 6px; font-size: 13px; font-family: inherit;
}
#panel input[type=number] { width: 60px; }
#panel .cm-monthday-row .cm-day-input { width: 44px; flex: none; }
/* min-width:0 (the flexbox default-override needed to let an item shrink
   below its content size at all) let the browser truncate month names
   ("Augu" instead of "August") once this was mounted somewhere with a
   slightly different inherited font/box-sizing than the standalone demo
   (found by embedding in maptools-uk, not visible in the standalone demo's
   own screenshots) - a real min-width fixes it regardless of host page. */
#panel .cm-monthday-row select { flex: 1; min-width: 78px; }

#panel-close {
  display: none; position: absolute; top: 6px; right: 8px; z-index: 1;
  background: none; border: none; color: var(--text-muted, #6b7280);
  font-size: 20px; line-height: 1; cursor: pointer; padding: 6px;
}

.mode-btn {
  background: var(--bg-secondary, #f4f7fb); color: var(--text-muted, #6b7280);
  border: 1px solid var(--border, rgba(0,0,0,0.1)); border-radius: var(--radius-sm, 6px);
  padding: 6px 12px; cursor: pointer; font-size: 13px; flex: 1; font-family: inherit;
}
.mode-btn.active { background: var(--primary, #2563eb); color: #ffffff; border-color: var(--primary, #2563eb); }

/* ---- Search (typeahead) ---- */
.cm-search-section { margin-top: 0; }
.cm-search-wrap { position: relative; }
#search-input {
  width: 100%; background: var(--bg-secondary, #f4f7fb); color: var(--text, #0f172a);
  border: 1px solid var(--border, rgba(0,0,0,0.1)); border-radius: var(--radius-sm, 6px);
  padding: 8px 10px; font-size: 14px; font-family: inherit;
}
.cm-search-results {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 30;
  background: var(--card, #ffffff); border: 1px solid var(--border, rgba(0,0,0,0.1));
  border-radius: var(--radius-md, 8px); box-shadow: var(--shadow-lg, 0 10px 15px -3px rgba(0,0,0,0.1));
  max-height: 280px; overflow-y: auto;
}
.cm-search-result {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  padding: 8px 10px; cursor: pointer; font-size: 13px;
}
.cm-search-result:hover, .cm-search-result.cm-active { background: var(--bg-secondary, #f4f7fb); }
.cm-search-result-name { font-weight: 600; color: var(--text, #0f172a); }
.cm-search-result-meta { font-size: 11px; color: var(--text-muted, #6b7280); text-transform: uppercase; letter-spacing: 0.03em; flex-shrink: 0; }
.cm-search-empty { padding: 10px; font-size: 12px; color: var(--text-muted, #6b7280); }

.hidden { display: none !important; }

/* ---- Three-layer popup content (shared by MapLibre popup + bottom sheet) ---- */
/* Widened from 240px (2026-08-29): the 3-card row (see .cm-cards-3 below)
   needs real room for values like "2.2mm/day"/"6.0h/day" - see that
   rule's own comment for the root cause. Bumped alongside app.js's
   maplibregl.Popup maxWidth (was 260px, now matches). */
.cm-popup { position: relative; font-size: 13px; color: var(--text, #0f172a); width: 270px; max-width: 80vw; }

/* Only rendered when pinned (click/tap) - see popup.js's `closable` option
   and app.js's showLocationInfo. Positioned relative to .cm-popup itself
   (not the bottom sheet or MapLibre's popup chrome) so the same markup and
   rule work in both mount points. */
.cm-popup-close {
  position: absolute; top: 6px; right: 8px; z-index: 1;
  background: none; border: none; color: var(--text-muted, #6b7280);
  cursor: pointer; padding: 4px;
}
.cm-popup-close .cm-icon { width: 16px; height: 16px; }

/* Shortlist star toggle - same "pinned only" rule as the close button,
   sits just to its left so both fit in the popup's top-right corner
   without crowding the headline text (see .cm-headline's right padding
   below, widened to make room for both). */
.cm-popup-candidate {
  position: absolute; top: 6px; right: 34px; z-index: 1;
  background: none; border: none; color: var(--text-muted, #6b7280);
  cursor: pointer; padding: 4px;
}
.cm-popup-candidate .cm-icon { width: 16px; height: 16px; }
.cm-popup-candidate-active { color: var(--warning, #f59e0b); }
.cm-popup-candidate-active .cm-icon { fill: currentColor; }
.cm-popup-candidate-disabled { cursor: not-allowed; opacity: 0.4; }

.cm-headline { padding: var(--spacing-md, 12px) 54px var(--spacing-sm, 8px) var(--spacing-md, 12px); }
.cm-place { font-weight: 700; font-size: 15px; }
.cm-verdict { color: var(--text-muted, #6b7280); font-size: 12.5px; margin-top: 2px; }

.cm-cards {
  display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
  background: var(--border, rgba(0,0,0,0.1));
  border-top: 1px solid var(--border, rgba(0,0,0,0.1));
  border-bottom: 1px solid var(--border, rgba(0,0,0,0.1));
}
/* Sea temp (sst) is the only card that's ever conditionally absent - an
   inland location has exactly 3 cards (tmax/precip/sunshine), a coastal
   one has 4. The 2-column grid above is correct for 4; left as-is for 3,
   the last card only fills the row's first column and the container's
   own background (the "grid line" colour) shows through the empty
   second cell as a blank grey box. Single row of 3 instead.
   FOUND 2026-08-29 (real production bug, screenshot): plain `1fr 1fr 1fr`
   is really `minmax(auto, 1fr)` per the CSS Grid spec - a track never
   shrinks below its content's natural (min-content) width, so 3 cards
   whose combined natural width exceeds the popup (confirmed: 263px of
   content in a 240px box) just push the WHOLE GRID wider than its
   container instead of sharing space evenly, and the popup's own
   `overflow:hidden` (see .maplibregl-popup-content below) silently
   clips whatever falls outside - "6.0h/day" truncating to "6.0h/da" is
   this, not a font/padding issue on its own. `minmax(0, 1fr)` forces
   real equal-width sharing (verified: grid now stays exactly 3x equal
   columns, matching the container). Combined with the 240->270px popup
   widen above and the smaller value font/padding just below, "2.2mm/day"
   (the widest realistic value) now fits with room to spare - checked at
   both desktop and the 380px mobile bottom-sheet width. */
.cm-cards-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cm-card {
  background: var(--card, #ffffff); padding: var(--spacing-sm, 10px) var(--spacing-md, 12px);
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
}
.cm-cards-3 .cm-card { padding-left: 8px; padding-right: 8px; }
.cm-card .cm-icon { width: 18px; height: 18px; color: var(--primary, #2563eb); margin-bottom: 2px; }
.cm-card-value { font-size: 16px; font-weight: 700; overflow-wrap: anywhere; }
.cm-cards-3 .cm-card-value { font-size: 14px; }
.cm-card-value-muted { font-size: 11.5px; font-weight: 500; color: var(--text-muted, #6b7280); }
.cm-card-label { font-size: 11px; color: var(--text-muted, #6b7280); }
.cm-card-unavailable .cm-icon { color: var(--text-muted, #6b7280); opacity: 0.5; }

.cm-details { padding: var(--spacing-xs, 4px) var(--spacing-md, 12px) var(--spacing-md, 12px); }
.cm-details summary {
  cursor: pointer; font-size: 12px; color: var(--text-muted, #6b7280); font-weight: 600;
  padding: var(--spacing-xs, 6px) 0; display: flex; align-items: center; gap: 4px; list-style: none;
}
.cm-details summary::-webkit-details-marker { display: none; }
.cm-chevron { width: 14px; height: 14px; transition: transform 0.15s ease; }
.cm-details[open] summary .cm-chevron { transform: rotate(180deg); }
.cm-details-body { padding-top: var(--spacing-xs, 6px); }
.cm-detail-row { display: flex; justify-content: space-between; padding: 3px 0; font-size: 12.5px; }
.cm-detail-label { color: var(--text-muted, #6b7280); }
.cm-detail-value-muted { color: var(--text-muted, #6b7280); font-style: italic; }
.cm-dev-note { margin-top: var(--spacing-sm, 8px); font-size: 10.5px; color: var(--warning, #f59e0b); }

.maplibregl-popup-content {
  background: var(--card, #ffffff); border-radius: var(--radius-lg, 10px);
  padding: 0; overflow: hidden;
  box-shadow: var(--shadow-lg, 0 10px 15px -3px rgba(0,0,0,0.1));
}
.maplibregl-popup-tip { border-top-color: var(--card, #ffffff) !important; }

/* ---- Mobile bottom sheet: same .cm-popup content, different mount point ---- */
#bottom-sheet {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 20;
  background: var(--card, #ffffff);
  border-top: 1px solid var(--border, rgba(0,0,0,0.1));
  border-radius: var(--radius-lg, 10px) var(--radius-lg, 10px) 0 0;
  box-shadow: var(--shadow-lg, 0 -10px 15px -3px rgba(0,0,0,0.1));
  max-height: 60%; overflow-y: auto;
  transform: translateY(0);
  transition: transform 0.2s ease;
}
#bottom-sheet.hidden { transform: translateY(100%); display: block !important; pointer-events: none; }
#bottom-sheet .cm-popup { width: 100%; max-width: none; }
#bottom-sheet .cm-sheet-handle {
  width: 36px; height: 4px; border-radius: 2px; background: var(--border, rgba(0,0,0,0.15));
  margin: 8px auto 0;
}
/* Close button is .cm-popup-close now (rendered inside the popup markup
   itself via popup.js's `closable` option), not a sheet-level element -
   the bottom sheet is always reached via tap, which is always "pinned",
   so it always gets one. */

/* ---- Narrow widget (<640px of the WIDGET's own width, not the
   viewport - see app.js's isNarrowWidget()): #panel collapses to a
   pill by default and opens as a bottom drawer, sharing the same
   bottom-anchored surface convention as #bottom-sheet so the two don't
   visually collide (app.js closes one when the other opens). At normal
   widths none of this applies - #panel stays the always-visible
   floating card it's always been. ---- */
#panel-pill {
  display: none; position: absolute; top: 8px; left: 8px; z-index: 15;
  background: var(--card, #ffffff); color: var(--text, #0f172a);
  border: 1px solid var(--border, rgba(0,0,0,0.1)); border-radius: var(--radius-xl, 999px);
  padding: 8px 14px; font-size: 13px; font-weight: 600; font-family: inherit;
  box-shadow: var(--shadow-lg, 0 10px 15px -3px rgba(0,0,0,0.1));
  cursor: pointer;
}

@container cm-widget (max-width: 640px) {
  #panel-pill { display: inline-flex; align-items: center; gap: 6px; }

  #panel {
    top: auto; left: 0; right: 0; bottom: 0; z-index: 21;
    width: 100%; max-width: none;
    border-radius: var(--radius-lg, 10px) var(--radius-lg, 10px) 0 0;
    max-height: 70%; overflow-y: auto;
    transform: translateY(100%);
    transition: transform 0.2s ease;
    pointer-events: none;
    padding-top: 34px; /* room for #panel-close */
  }
  #panel.cm-panel-open { transform: translateY(0); pointer-events: auto; }
  #panel-close { display: block; }
}

/* ---- Candidate pins (shortlist markers) ----
   Distinct from the explore-mode hover/pinned popup entirely - these
   persist on the map as a standing shortlist. z-index above
   #filter-canvas (5) so they never disappear under Filter mode's
   threshold shading; MapLibre positions marker elements itself
   (absolute, transformed to the map coordinate), this class only adds
   the stacking + visual treatment. */
.cm-candidate-marker {
  z-index: 6; display: flex; align-items: center; gap: 4px;
  background: var(--card, #ffffff); color: var(--text, #0f172a);
  border: 1.5px solid var(--warning, #f59e0b); border-radius: var(--radius-xl, 999px);
  padding: 3px 8px 3px 6px; font-size: 11.5px; font-weight: 600; font-family: inherit;
  box-shadow: var(--shadow-lg, 0 4px 6px -2px rgba(0,0,0,0.15));
  cursor: pointer; white-space: nowrap; line-height: 1.3;
}
.cm-candidate-marker::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
  background: var(--warning, #f59e0b);
}
.cm-candidate-label { overflow: hidden; text-overflow: ellipsis; max-width: 140px; }
.cm-candidate-remove {
  background: none; border: none; color: var(--text-muted, #6b7280); cursor: pointer;
  padding: 0; margin: 0 -2px 0 2px; display: flex; align-items: center; flex-shrink: 0;
}
.cm-candidate-remove .cm-icon { width: 12px; height: 12px; }

/* Collapsed mode - no label, just the dot, so a cluster of shortlisted
   places doesn't turn into an unreadable pile of overlapping pills.
   app.js decides when to apply this (narrow widget + zoomed out past a
   threshold - see requestCandidateRefresh()), not a pure CSS breakpoint,
   since it depends on the MAP's zoom, not just the widget's width. */
.cm-candidate-marker.cm-candidate-dot {
  padding: 0; width: 12px; height: 12px; border-width: 2px;
}
.cm-candidate-marker.cm-candidate-dot::before { margin: auto; }
.cm-candidate-marker.cm-candidate-dot .cm-candidate-label,
.cm-candidate-marker.cm-candidate-dot .cm-candidate-remove { display: none; }
