/* ============================================================================
   EnergyMaster AI — Frontend Styles
   Design: Bloomberg Terminal ∕ Refinitiv Eikon aesthetic
   Fonts: IBM Plex Mono (data) + Barlow Condensed (labels)
   ============================================================================ */

@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@300;400;500;600&family=Barlow+Condensed:wght@300;400;500;600;700&display=swap');

/* ── CSS Custom Properties ─────────────────────────────────────────────────── */
:root {
  /* Dark theme (default) */
  --ema-bg:           #0a0c10;
  --ema-bg-panel:     #0f1218;
  --ema-bg-card:      #131820;
  --ema-bg-input:     #1a2030;
  --ema-border:       #1e2738;
  --ema-border-soft:  #16202e;

  --ema-text:         #c8d4e8;
  --ema-text-dim:     #5a6a82;
  --ema-text-bright:  #e8f0fc;
  --ema-text-label:   #7b8fa8;

  --ema-amber:        #F59E0B;
  --ema-amber-dim:    #92600A;
  --ema-amber-glow:   rgba(245, 158, 11, 0.12);
  --ema-cyan:         #22D3EE;
  --ema-cyan-dim:     rgba(34, 211, 238, 0.15);

  --ema-up:           #22c55e;
  --ema-up-bg:        rgba(34, 197, 94, 0.08);
  --ema-down:         #ef4444;
  --ema-down-bg:      rgba(239, 68, 68, 0.08);
  --ema-flat:         #64748b;

  --ema-bull:         #22c55e;
  --ema-bear:         #ef4444;
  --ema-neutral:      #94a3b8;

  --ema-radius:       4px;
  --ema-radius-lg:    8px;
  --ema-shadow:       0 2px 16px rgba(0,0,0,0.6);
  --ema-shadow-glow:  0 0 24px rgba(245, 158, 11, 0.08);

  --ema-font-mono:    'IBM Plex Mono', 'Courier New', monospace;
  --ema-font-ui:      'Barlow Condensed', system-ui, sans-serif;

  --ema-ticker-height: 52px;
  --ema-transition:    180ms ease;

  /* Uniform height every dashboard-grid widget panel is pinned to (see
   * "Frame 2" rules below) — a widget with more to show than this scrolls
   * internally rather than growing the row. Tweak this one value to make
   * every panel taller/shorter across the whole grid at once. */
  --ema-panel-height: 420px;
}

/* Light theme overrides */
.ema-theme--light {
  --ema-bg:          #f0f4fa;
  --ema-bg-panel:    #e8edf5;
  --ema-bg-card:     #ffffff;
  --ema-bg-input:    #f4f7fc;
  --ema-border:      #c8d4e8;
  --ema-border-soft: #dce4f0;
  --ema-text:        #1e2d40;
  --ema-text-dim:    #8096b4;
  --ema-text-bright: #0f1a2e;
  --ema-text-label:  #5a6e88;
  --ema-amber-glow:  rgba(245, 158, 11, 0.06);
}

/* Terminal (green-on-black) theme */
.ema-theme--terminal {
  --ema-bg:          #000000;
  --ema-bg-panel:    #020402;
  --ema-bg-card:     #050905;
  --ema-bg-input:    #0a0f0a;
  --ema-border:      #0f2010;
  --ema-border-soft: #081208;
  --ema-text:        #00cc44;
  --ema-text-dim:    #006622;
  --ema-text-bright: #00ff55;
  --ema-text-label:  #009933;
  --ema-amber:       #00ff55;
  --ema-amber-dim:   #006622;
  --ema-amber-glow:  rgba(0, 255, 85, 0.08);
  --ema-cyan:        #00ff55;
  --ema-up:          #00ff55;
  --ema-down:        #ff2244;
}

/* ── Base Widget Container ──────────────────────────────────────────────────── */
.ema-widget {
  font-family: var(--ema-font-ui);
  background: var(--ema-bg);
  color: var(--ema-text);
  border: 1px solid var(--ema-border);
  border-radius: var(--ema-radius-lg);
  overflow: hidden;
  position: relative;
  box-shadow: var(--ema-shadow);
  transition: box-shadow var(--ema-transition);
}

.ema-widget:hover {
  box-shadow: var(--ema-shadow), var(--ema-shadow-glow);
}

/* Scanline overlay (terminal aesthetic) */
.ema-widget::before {
  content: '';
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    0deg,
    transparent,
    transparent 2px,
    rgba(0,0,0,0.03) 2px,
    rgba(0,0,0,0.03) 4px
  );
  pointer-events: none;
  z-index: 0;
}

.ema-widget > * { position: relative; z-index: 1; }

/* ── Widget Header ──────────────────────────────────────────────────────────── */
.ema-widget-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  background: var(--ema-bg-panel);
  border-bottom: 1px solid var(--ema-border);
  gap: 12px;
}

.ema-widget-title {
  font-family: var(--ema-font-ui);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ema-amber);
}

.ema-widget-badge {
  font-family: var(--ema-font-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.1em;
  padding: 2px 6px;
  border-radius: 2px;
  text-transform: uppercase;
}

.ema-badge--live {
  background: var(--ema-up-bg);
  color: var(--ema-up);
  border: 1px solid rgba(34, 197, 94, 0.2);
  animation: ema-pulse-live 2s infinite;
}

@keyframes ema-pulse-live {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.6; }
}

.ema-timestamp {
  font-family: var(--ema-font-mono);
  font-size: 10px;
  color: var(--ema-text-dim);
}

/* ── Loading Skeleton ───────────────────────────────────────────────────────── */
.ema-widget__loader {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 120px;
  gap: 14px;
  padding: 32px;
}

.ema-loader-ring {
  display: block;
  width: 36px;
  height: 36px;
  border: 2px solid var(--ema-border);
  border-top-color: var(--ema-amber);
  border-radius: 50%;
  animation: ema-spin 0.8s linear infinite;
}

@keyframes ema-spin {
  to { transform: rotate(360deg); }
}

.ema-loader-text {
  font-family: var(--ema-font-mono);
  font-size: 11px;
  color: var(--ema-text-dim);
  letter-spacing: 0.08em;
}

/* ── Ticker ─────────────────────────────────────────────────────────────────── */
.ema-widget--ticker {
  border-radius: var(--ema-radius);
  overflow: hidden;
  height: var(--ema-ticker-height);
  border-left: 3px solid var(--ema-amber);
}

.ema-ticker-track {
  display: flex;
  align-items: center;
  height: 100%;
  white-space: nowrap;
  animation: ema-ticker-scroll var(--scroll-duration, 40s) linear infinite;
  will-change: transform;
}

.ema-ticker-track:hover { animation-play-state: paused; }

.ema-ticker-compact-status {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 100%;
  padding: 0 16px;
  font-family: var(--ema-font-mono);
  font-size: 11px;
  color: var(--ema-text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ema-ticker-compact-status--error { color: var(--ema-down); }

.ema-ticker-compact-retry {
  flex-shrink: 0;
  font-family: var(--ema-font-ui);
  font-size: 10px;
  font-weight: 700;
  padding: 2px 9px;
  background: transparent;
  color: var(--ema-amber);
  border: 1px solid var(--ema-amber-dim);
  border-radius: var(--ema-radius);
  cursor: pointer;
}

.ema-ticker-compact-retry:hover { background: var(--ema-amber-glow); }

@keyframes ema-ticker-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

.ema-ticker-item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0 20px;
  font-family: var(--ema-font-mono);
  font-size: 12.5px;
  font-weight: 500;
  border-right: 1px solid var(--ema-border-soft);
  cursor: default;
}

.ema-ticker-symbol {
  color: var(--ema-text-label);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.06em;
}

.ema-ticker-price { color: var(--ema-text-bright); }

.ema-ticker-change {
  font-size: 11px;
  font-weight: 600;
  padding: 1px 5px;
  border-radius: 2px;
}

.ema-ticker-change--up {
  color: var(--ema-up);
  background: var(--ema-up-bg);
}
.ema-ticker-change--down {
  color: var(--ema-down);
  background: var(--ema-down-bg);
}

.ema-ticker-divider {
  display: inline-block;
  width: 1px;
  height: 20px;
  background: var(--ema-border);
  margin: 0 10px;
}

/* ── Heatmap ─────────────────────────────────────────────────────────────────── */
.ema-heatmap-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 4px;
  padding: 12px;
}

.ema-heatmap-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 16px 8px;
  border-radius: var(--ema-radius);
  border: 1px solid transparent;
  cursor: default;
  transition: transform var(--ema-transition), border-color var(--ema-transition);
  position: relative;
  overflow: hidden;
}

.ema-heatmap-tile:hover {
  transform: scale(1.02);
  z-index: 2;
}

.ema-heatmap-tile--up   { background: var(--ema-up-bg);   border-color: rgba(34,197,94,0.2); }
.ema-heatmap-tile--down { background: var(--ema-down-bg); border-color: rgba(239,68,68,0.2); }
.ema-heatmap-tile--flat { background: rgba(100,116,139,0.06); border-color: rgba(100,116,139,0.15); }

/* Intensity fill overlay */
.ema-heatmap-tile::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--tile-fill, transparent);
  pointer-events: none;
}

.ema-tile-symbol {
  font-family: var(--ema-font-ui);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--ema-text-bright);
}

.ema-tile-price {
  font-family: var(--ema-font-mono);
  font-size: 13px;
  font-weight: 500;
  color: var(--ema-text-bright);
}

.ema-tile-change {
  font-family: var(--ema-font-mono);
  font-weight: 700;
  font-size: 14px;
}

.ema-tile-change--up   { color: var(--ema-up); }
.ema-tile-change--down { color: var(--ema-down); }
.ema-tile-change--flat { color: var(--ema-flat); }

/* ── Sector Explorer (2.15.0) ──────────────────────────────────────────────── */
.ema-sector-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 10px 12px 0;
  border-bottom: 1px solid var(--ema-border);
}

.ema-sector-tab {
  font-family: var(--ema-font-ui);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ema-text-dim);
  background: var(--ema-bg-input);
  border: 1px solid var(--ema-border);
  border-bottom: none;
  border-radius: var(--ema-radius) var(--ema-radius) 0 0;
  padding: 7px 12px;
  cursor: pointer;
  transition: color var(--ema-transition), background var(--ema-transition);
}

.ema-sector-tab:hover {
  color: var(--ema-text-bright);
}

.ema-sector-tab--active {
  color: var(--ema-amber);
  background: var(--ema-bg-card);
  border-color: var(--ema-amber-dim);
  box-shadow: inset 0 2px 0 var(--ema-amber);
}

.ema-sector-body {
  min-height: 120px;
  position: relative;
}

.ema-sector-loader {
  position: static;
  padding: 32px 0;
}

.ema-sector-empty {
  padding: 32px 16px;
  text-align: center;
  font-family: var(--ema-font-ui);
  font-size: 13px;
  color: var(--ema-text-dim);
}

/* ── Prediction Window ──────────────────────────────────────────────────────── */
.ema-prediction-card {
  padding: 20px;
}

.ema-prediction-asset {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 20px;
}

.ema-prediction-symbol {
  font-family: var(--ema-font-ui);
  font-weight: 700;
  font-size: 22px;
  color: var(--ema-amber);
  letter-spacing: 0.04em;
}

.ema-prediction-price {
  font-family: var(--ema-font-mono);
  font-size: 20px;
  font-weight: 500;
  color: var(--ema-text-bright);
}

.ema-prediction-change {
  font-family: var(--ema-font-mono);
  font-size: 13px;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 2px;
}

.ema-scenarios {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-bottom: 16px;
}

.ema-scenario {
  padding: 14px 10px;
  border-radius: var(--ema-radius);
  border: 1px solid var(--ema-border);
  text-align: center;
  transition: border-color var(--ema-transition);
}

.ema-scenario:hover { border-color: var(--ema-amber-dim); }

.ema-scenario--bull { border-top: 3px solid var(--ema-bull); }
.ema-scenario--base { border-top: 3px solid var(--ema-amber); }
.ema-scenario--bear { border-top: 3px solid var(--ema-bear); }

.ema-scenario-label {
  font-family: var(--ema-font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ema-text-label);
  margin-bottom: 6px;
}

.ema-scenario-prob {
  font-family: var(--ema-font-mono);
  font-size: 22px;
  font-weight: 600;
  line-height: 1;
  margin-bottom: 4px;
}

.ema-scenario--bull .ema-scenario-prob { color: var(--ema-bull); }
.ema-scenario--base .ema-scenario-prob { color: var(--ema-amber); }
.ema-scenario--bear .ema-scenario-prob { color: var(--ema-bear); }

.ema-scenario-target {
  font-family: var(--ema-font-mono);
  font-size: 12px;
  color: var(--ema-text-dim);
}

.ema-confidence-bar-wrap {
  margin-bottom: 16px;
}

.ema-confidence-label {
  display: flex;
  justify-content: space-between;
  font-family: var(--ema-font-ui);
  font-size: 11px;
  color: var(--ema-text-label);
  letter-spacing: 0.06em;
  margin-bottom: 6px;
}

.ema-confidence-bar {
  height: 4px;
  background: var(--ema-border);
  border-radius: 2px;
  overflow: hidden;
}

.ema-confidence-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--ema-amber-dim), var(--ema-amber));
  border-radius: 2px;
  transition: width 0.8s cubic-bezier(0.4, 0, 0.2, 1);
}

.ema-mindset {
  padding: 14px;
  background: var(--ema-bg-panel);
  border-radius: var(--ema-radius);
  border-left: 3px solid var(--ema-amber-dim);
  font-family: var(--ema-font-mono);
  font-size: 11.5px;
  line-height: 1.7;
  color: var(--ema-text);
}

.ema-mindset-label {
  font-family: var(--ema-font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ema-amber);
  margin-bottom: 8px;
}

.ema-actionable {
  margin-top: 14px;
  padding: 12px 14px;
  background: var(--ema-amber-glow);
  border: 1px solid var(--ema-amber-dim);
  border-radius: var(--ema-radius);
  font-family: var(--ema-font-ui);
  font-size: 13px;
  font-weight: 500;
  color: var(--ema-text-bright);
  line-height: 1.5;
}

/* ── AI Disclosure Badge ─────────────────────────────────────────────────────
 * Deliberately styled with a neutral/caution border (not brand amber) so it
 * reads as a caveat, not a confidence-boosting decoration. Rendered from
 * server-verified metadata (see Disclosure::for_tools) — always present on
 * AI-narrated widgets regardless of what the model itself said.
 * ──────────────────────────────────────────────────────────────────────── */
.ema-disclosure {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.ema-disclosure-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 8px 12px;
  background: var(--ema-bg-panel);
  border: 1px dashed var(--ema-border);
  border-radius: var(--ema-radius);
  font-family: var(--ema-font-mono);
  font-size: 10.5px;
  line-height: 1.5;
  color: var(--ema-text-dim);
}

.ema-disclosure--ai_estimate_numeric {
  border-color: var(--ema-down);
  border-style: solid;
}

.ema-disclosure-icon {
  flex-shrink: 0;
  display: flex;
  width: 13px;
  height: 13px;
  margin-top: 1px;
}

.ema-disclosure-icon svg { width: 100%; height: 100%; }
.ema-disclosure--ai_estimate_numeric .ema-disclosure-icon { color: var(--ema-down); }

.ema-disclosure-label {
  flex-shrink: 0;
  font-family: var(--ema-font-ui);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 9.5px;
  color: var(--ema-text);
}

.ema-disclosure-note {
  color: var(--ema-text-dim);
}

.ema-chat-message--ai .ema-disclosure {
  margin-top: 8px;
}

/* ── News Digest ─────────────────────────────────────────────────────────────── */
.ema-news-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.ema-news-item {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--ema-border-soft);
  transition: background var(--ema-transition);
  align-items: start;
}

.ema-news-item:hover { background: rgba(255,255,255,0.02); }
.ema-news-item:last-child { border-bottom: none; }

.ema-news-sentiment {
  width: 3px;
  align-self: stretch;
  border-radius: 2px;
  flex-shrink: 0;
}

.ema-news-sentiment--bullish { background: var(--ema-bull); }
.ema-news-sentiment--bearish { background: var(--ema-bear); }
.ema-news-sentiment--neutral { background: var(--ema-flat); }

.ema-news-title {
  font-family: var(--ema-font-ui);
  font-weight: 600;
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--ema-text-bright);
  margin-bottom: 4px;
}

.ema-news-title a {
  color: inherit;
  text-decoration: none;
  transition: color var(--ema-transition);
}

.ema-news-title a:hover { color: var(--ema-amber); }

.ema-news-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--ema-font-mono);
  font-size: 10px;
  color: var(--ema-text-dim);
}

.ema-news-source {
  color: var(--ema-amber-dim);
  font-weight: 600;
}

.ema-news-badge {
  padding: 1px 5px;
  border-radius: 2px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ema-news-badge--bullish { background: var(--ema-up-bg);   color: var(--ema-up);   }
.ema-news-badge--bearish { background: var(--ema-down-bg); color: var(--ema-down); }

/* Infinite-scroll sentinel row — sits as the list's last <li>, either the
 * load-more trigger an IntersectionObserver watches (see initNewsDigest in
 * energymaster.js) or, once the RSS pool is exhausted, a plain end note. */
.ema-news-sentinel {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 16px;
  font-family: var(--ema-font-mono);
  font-size: 11px;
  color: var(--ema-text-dim);
}

.ema-news-sentinel--end { font-style: italic; }

.ema-loader-ring--sm {
  width: 14px;
  height: 14px;
  border-width: 2px;
}

/* ── AI Chat Terminal ────────────────────────────────────────────────────────── */
.ema-widget--chat {
  /* The widget container must be a fixed-height flex column so the
     input bar is always visible and messages scroll inside. */
  display: flex;
  flex-direction: column;
  overflow: hidden; /* no outer scroll — only inner message area scrolls */
}

.ema-chat {
  display: flex;
  flex-direction: column;
  flex: 1;            /* fill the widget */
  min-height: 0;      /* CRITICAL — allows flex child to shrink below content size */
  overflow: hidden;
}

.ema-chat-messages {
  flex: 1;
  min-height: 0;      /* CRITICAL — prevents messages from pushing input off-screen */
  overflow-y: auto;
  padding: 16px;
  scroll-behavior: smooth;
  scrollbar-width: thin;
  scrollbar-color: var(--ema-border) transparent;
}

.ema-chat-messages::-webkit-scrollbar       { width: 4px; }
.ema-chat-messages::-webkit-scrollbar-track { background: transparent; }
.ema-chat-messages::-webkit-scrollbar-thumb { background: var(--ema-border); border-radius: 2px; }

.ema-chat-message {
  margin-bottom: 16px;
  animation: ema-fade-in 0.2s ease;
}

@keyframes ema-fade-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

.ema-chat-message--user { text-align: right; }

.ema-chat-bubble {
  display: inline-block;
  max-width: 85%;
  padding: 10px 14px;
  border-radius: var(--ema-radius-lg);
  font-family: var(--ema-font-ui);
  font-size: 13.5px;
  line-height: 1.5;
}

.ema-chat-message--user .ema-chat-bubble {
  background: var(--ema-amber-glow);
  border: 1px solid var(--ema-amber-dim);
  color: var(--ema-text-bright);
  border-bottom-right-radius: 2px;
}

.ema-chat-message--ai .ema-chat-bubble {
  background: var(--ema-bg-panel);
  border: 1px solid var(--ema-border);
  color: var(--ema-text);
  border-bottom-left-radius: 2px;
  text-align: left;
}

.ema-chat-message--ai .ema-chat-bubble pre,
.ema-chat-message--ai .ema-chat-bubble code {
  font-family: var(--ema-font-mono);
  font-size: 11px;
  background: var(--ema-bg-card);
  padding: 2px 4px;
  border-radius: 2px;
  color: var(--ema-cyan);
}

.ema-chat-sender {
  font-family: var(--ema-font-mono);
  font-size: 10px;
  color: var(--ema-text-dim);
  margin-bottom: 4px;
  letter-spacing: 0.06em;
}

.ema-chat-message--ai .ema-chat-sender { color: var(--ema-amber); }

.ema-chat-thinking {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 14px;
  background: var(--ema-bg-panel);
  border: 1px solid var(--ema-border);
  border-radius: var(--ema-radius-lg);
  border-bottom-left-radius: 2px;
  font-family: var(--ema-font-mono);
  font-size: 11px;
  color: var(--ema-text-dim);
  display: inline-flex;
}

.ema-thinking-dots { display: flex; gap: 3px; }
.ema-thinking-dots span {
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--ema-amber);
  animation: ema-bounce 1.2s infinite;
}
.ema-thinking-dots span:nth-child(2) { animation-delay: 0.2s; }
.ema-thinking-dots span:nth-child(3) { animation-delay: 0.4s; }

@keyframes ema-bounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
  30%            { transform: translateY(-4px); opacity: 1; }
}

.ema-chat-input-area {
  display: flex;
  gap: 8px;
  padding: 12px 16px;
  background: var(--ema-bg-panel);
  border-top: 1px solid var(--ema-border);
}

.ema-chat-input {
  flex: 1;
  background: var(--ema-bg-input);
  border: 1px solid var(--ema-border);
  border-radius: var(--ema-radius);
  padding: 10px 14px;
  font-family: var(--ema-font-mono);
  font-size: 12.5px;
  color: var(--ema-text);
  outline: none;
  transition: border-color var(--ema-transition);
  resize: none;
}

.ema-chat-input::placeholder { color: var(--ema-text-dim); }
.ema-chat-input:focus { border-color: var(--ema-amber-dim); }

.ema-chat-send {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  background: var(--ema-amber);
  border: none;
  border-radius: var(--ema-radius);
  color: #000;
  cursor: pointer;
  transition: background var(--ema-transition), transform var(--ema-transition);
  flex-shrink: 0;
}

.ema-chat-send:hover   { background: #fbbf24; }
.ema-chat-send:active  { transform: scale(0.96); }
.ema-chat-send:disabled { background: var(--ema-border); cursor: not-allowed; color: var(--ema-text-dim); }

.ema-chat-send svg { width: 16px; height: 16px; }

/* ── Correlation Matrix ──────────────────────────────────────────────────────── */
.ema-matrix-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--ema-font-mono);
  font-size: 11px;
}

.ema-matrix-table th {
  font-family: var(--ema-font-ui);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--ema-text-label);
  padding: 8px;
  border-bottom: 1px solid var(--ema-border);
  white-space: nowrap;
}

.ema-matrix-table td {
  padding: 8px;
  text-align: center;
  border: 1px solid var(--ema-border-soft);
  font-weight: 500;
}

.ema-matrix-cell--pos  { color: var(--ema-up);   }
.ema-matrix-cell--neg  { color: var(--ema-down); }
.ema-matrix-cell--diag { color: var(--ema-text-dim); }

/* ── Inline error card ────────────────────────────────────────────────────────
 * Used by errorNode() in energymaster.js wherever a failure (API error,
 * network timeout, partial data, etc.) is shown inside a chat bubble or
 * message stream — replaces a bare "[warning-glyph] message" string with a small labeled
 * card so failures read as an intentional part of the interface.
 * ──────────────────────────────────────────────────────────────────────── */
.ema-inline-error {
  padding: 10px 12px;
  background: var(--ema-down-bg);
  border: 1px solid var(--ema-down);
  border-left-width: 3px;
  border-radius: var(--ema-radius);
}

.ema-inline-error-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--ema-font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ema-down);
  margin-bottom: 4px;
}

.ema-inline-error-icon { display: flex; width: 13px; height: 13px; }
.ema-inline-error-icon svg { width: 100%; height: 100%; }

.ema-inline-error-text {
  font-family: var(--ema-font-mono);
  font-size: 12px;
  line-height: 1.5;
  color: var(--ema-text);
}

.ema-ticker-compact-status-icon { display: flex; width: 14px; height: 14px; flex-shrink: 0; }
.ema-ticker-compact-status-icon svg { width: 100%; height: 100%; }

/* ── Error State ─────────────────────────────────────────────────────────────── */
.ema-widget-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 32px;
  min-height: 100px;
  text-align: center;
}

.ema-widget-error-icon {
  display: flex;
  width: 28px;
  height: 28px;
  color: var(--ema-down);
}

.ema-widget-error-icon svg { width: 100%; height: 100%; }

.ema-widget-error-text {
  font-family: var(--ema-font-mono);
  font-size: 12px;
  color: var(--ema-text-dim);
}

.ema-retry-btn {
  font-family: var(--ema-font-ui);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  padding: 6px 14px;
  border: 1px solid var(--ema-amber-dim);
  background: transparent;
  color: var(--ema-amber);
  border-radius: var(--ema-radius);
  cursor: pointer;
  transition: all var(--ema-transition);
}

.ema-retry-btn:hover {
  background: var(--ema-amber-glow);
  border-color: var(--ema-amber);
}

/* ── Utility classes ─────────────────────────────────────────────────────────── */
.ema-up   { color: var(--ema-up)   !important; }
.ema-down { color: var(--ema-down) !important; }
.ema-flat { color: var(--ema-flat) !important; }

.ema-mono { font-family: var(--ema-font-mono); }
.ema-ui   { font-family: var(--ema-font-ui); }

.ema-sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  border: 0;
}

/* ── Responsive ──────────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
  .ema-scenarios          { grid-template-columns: 1fr; }
  .ema-heatmap-grid       { grid-template-columns: repeat(2, 1fr); }
  .ema-widget-header      { flex-wrap: wrap; }
  .ema-ticker-item        { padding: 0 12px; }
  .ema-chat-bubble        { max-width: 95%; }
}

/* ── Print ───────────────────────────────────────────────────────────────────── */
@media print {
  .ema-widget { box-shadow: none; border: 1px solid #ccc; }
  .ema-chat-input-area,
  .ema-retry-btn { display: none; }
}

/* ── Alert Feed ──────────────────────────────────────────────────────────────── */
.ema-widget--alert_feed {
  border-left: 3px solid var(--ema-down);
}

.ema-alert-item {
  border-radius: var(--ema-radius);
  padding: 12px 14px;
  margin: 8px 8px 0;
  border: 1px solid transparent;
  transition: border-color var(--ema-transition);
}

.ema-alert-item:last-child { margin-bottom: 8px; }

.ema-alert-item--critical { border-left: 4px solid var(--ema-down);   background: var(--ema-down-bg); }
.ema-alert-item--high     { border-left: 4px solid #f97316;           background: rgba(249,115,22,.06); }
.ema-alert-item--medium   { border-left: 4px solid var(--ema-amber);  background: var(--ema-amber-glow); }
.ema-alert-item--low      { border-left: 4px solid var(--ema-up);     background: var(--ema-up-bg); }

.ema-alert-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
}

.ema-alert-urgency-badge {
  font-family: var(--ema-font-mono);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 2px;
  border: 1px solid currentColor;
}

.ema-alert-symbol {
  font-family: var(--ema-font-ui);
  font-weight: 700;
  font-size: 14px;
  color: var(--ema-text-bright);
}

.ema-alert-price {
  font-family: var(--ema-font-mono);
  font-size: 12px;
  margin-left: auto;
}

.ema-alert-message {
  font-family: var(--ema-font-ui);
  font-size: 13px;
  color: var(--ema-text);
  line-height: 1.45;
  margin-bottom: 5px;
}

.ema-alert-action {
  font-family: var(--ema-font-mono);
  font-size: 11px;
  color: var(--ema-text-dim);
  font-style: italic;
}

.ema-alert-action::before { content: '→ '; color: var(--ema-amber); }

.ema-alert-ts {
  font-family: var(--ema-font-mono);
  font-size: 9px;
  color: var(--ema-text-dim);
  margin-top: 4px;
}

/* ── Futures Curve ───────────────────────────────────────────────────────────── */
.ema-widget--futures_curve {}

.ema-curve-structure {
  padding: 8px 16px;
  font-family: var(--ema-font-mono);
  font-size: 11px;
  font-weight: 600;
  border-bottom: 1px solid var(--ema-border);
  letter-spacing: 0.04em;
}

.ema-curve-structure--contango      { color: var(--ema-down); }
.ema-curve-structure--backwardation { color: var(--ema-up);   }
.ema-curve-structure--flat          { color: var(--ema-flat); }

.ema-curve-table {
  width: 100%;
  border-collapse: collapse;
}

.ema-curve-table th {
  padding: 8px 16px;
  font-family: var(--ema-font-ui);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ema-text-label);
  border-bottom: 1px solid var(--ema-border);
}

.ema-curve-table td {
  padding: 10px 16px;
  border-bottom: 1px solid var(--ema-border-soft);
}

.ema-curve-table tr:last-child td { border-bottom: none; }
.ema-curve-table tr:hover td      { background: rgba(255,255,255,.02); }

.ema-curve-label {
  font-family: var(--ema-font-ui);
  font-weight: 700;
  font-size: 13px;
  color: var(--ema-amber);
  letter-spacing: 0.04em;
}

.ema-curve-price {
  font-family: var(--ema-font-mono);
  font-size: 14px;
  font-weight: 500;
  color: var(--ema-text-bright);
  text-align: right;
}

.ema-curve-spread {
  font-family: var(--ema-font-mono);
  font-size: 12px;
  font-weight: 600;
  text-align: right;
}

/* SVG Sparkline bar for curve */
.ema-curve-bar-cell { text-align: right; padding-right: 16px; }
.ema-curve-bar {
  display: inline-block;
  height: 6px;
  border-radius: 3px;
  min-width: 4px;
  vertical-align: middle;
  transition: width 0.6s ease;
}
.ema-curve-bar--contango      { background: var(--ema-down); }
.ema-curve-bar--backwardation { background: var(--ema-up);   }
.ema-curve-bar--flat          { background: var(--ema-flat); }

/* ── Correlation Matrix Table ────────────────────────────────────────────────── */
.ema-matrix-wrap { padding: 12px; overflow-x: auto; }

.ema-matrix-table th:first-child,
.ema-matrix-table td:first-child {
  text-align: left;
  font-weight: 700;
  color: var(--ema-amber);
  padding-left: 12px;
}

/* Heat-fill cells */
.ema-matrix-cell {
  min-width: 60px;
  font-family: var(--ema-font-mono);
  font-size: 12px;
  font-weight: 600;
  border-radius: 2px;
  transition: background var(--ema-transition);
}

/* ── Futures Curve Mini-Chart SVG ────────────────────────────────────────────── */
.ema-sparkline {
  display: block;
  width: 100%;
  height: 64px;
  overflow: visible;
}

.ema-sparkline-line { fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.ema-sparkline-fill { opacity: 0.15; }
.ema-sparkline-dot  { r: 3; }

.ema-sparkline--up   .ema-sparkline-line { stroke: var(--ema-up); }
.ema-sparkline--up   .ema-sparkline-fill { fill:   var(--ema-up); }
.ema-sparkline--up   .ema-sparkline-dot  { fill:   var(--ema-up); }
.ema-sparkline--down .ema-sparkline-line { stroke: var(--ema-down); }
.ema-sparkline--down .ema-sparkline-fill { fill:   var(--ema-down); }
.ema-sparkline--down .ema-sparkline-dot  { fill:   var(--ema-down); }
.ema-sparkline--flat .ema-sparkline-line { stroke: var(--ema-flat); }
.ema-sparkline--flat .ema-sparkline-fill { fill:   var(--ema-flat); }

/* ── Technical Analysis ──────────────────────────────────────────────────────── */
.ema-ta-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 8px;
  padding: 12px;
}

.ema-ta-tile {
  background: var(--ema-bg-panel);
  border: 1px solid var(--ema-border);
  border-radius: var(--ema-radius);
  padding: 12px;
  text-align: center;
}

.ema-ta-label {
  font-family: var(--ema-font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ema-text-label);
  margin-bottom: 6px;
}

.ema-ta-value {
  font-family: var(--ema-font-mono);
  font-size: 18px;
  font-weight: 600;
  color: var(--ema-text-bright);
  line-height: 1;
  margin-bottom: 4px;
}

.ema-ta-signal {
  font-family: var(--ema-font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ema-ta-signal--buy    { color: var(--ema-up); }
.ema-ta-signal--sell   { color: var(--ema-down); }
.ema-ta-signal--neutral{ color: var(--ema-flat); }

/* ── Summary prose block (for AI text responses) ─────────────────────────────── */
.ema-prose {
  padding: 16px;
  font-family: var(--ema-font-ui);
  font-size: 13.5px;
  line-height: 1.7;
  color: var(--ema-text);
}

.ema-prose strong  { color: var(--ema-text-bright); font-weight: 600; }
.ema-prose code    { font-family: var(--ema-font-mono); font-size: 12px; color: var(--ema-cyan); background: var(--ema-bg-panel); padding: 1px 4px; border-radius: 2px; }
.ema-prose h3      { font-family: var(--ema-font-ui); font-size: 12px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ema-amber); margin: 14px 0 6px; }
.ema-prose p       { margin: 0 0 10px; }
.ema-prose ul      { padding-left: 18px; }
.ema-prose li      { margin-bottom: 4px; }

/* ── Scrollbar global theming ─────────────────────────────────────────────────── */
.ema-widget { scrollbar-width: thin; scrollbar-color: var(--ema-border) transparent; }
.ema-widget::-webkit-scrollbar       { width: 4px; height: 4px; }
.ema-widget::-webkit-scrollbar-track { background: transparent; }
.ema-widget::-webkit-scrollbar-thumb { background: var(--ema-border); border-radius: 2px; }

/* ── Date Range Toolbar ─────────────────────────────────────────────────────── */
.ema-date-toolbar {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px 14px;
  background: var(--ema-bg-panel);
  border-bottom: 1px solid var(--ema-border);
  flex-wrap: wrap;
}

.ema-date-btn {
  font-family: var(--ema-font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 3px 8px;
  border: 1px solid var(--ema-border);
  border-radius: 2px;
  background: transparent;
  color: var(--ema-text-label);
  cursor: pointer;
  transition: all 0.15s;
  line-height: 1.4;
}

.ema-date-btn:hover { border-color: var(--ema-amber-dim); color: var(--ema-amber); }
.ema-date-btn.active {
  background: var(--ema-amber-glow);
  border-color: var(--ema-amber);
  color: var(--ema-amber);
}

.ema-date-sep {
  display: block;
  width: 1px;
  height: 16px;
  background: var(--ema-border);
  margin: 0 4px;
  flex-shrink: 0;
}

.ema-date-input {
  font-family: var(--ema-font-mono);
  font-size: 10px;
  padding: 3px 6px;
  background: var(--ema-bg-card);
  border: 1px solid var(--ema-border);
  border-radius: 2px;
  color: var(--ema-text);
  outline: none;
  transition: border-color 0.15s;
  cursor: pointer;
  color-scheme: dark;
}

.ema-date-input:focus { border-color: var(--ema-amber-dim); }

/* Light theme date input */
.ema-theme--light .ema-date-input { color-scheme: light; }

/* ── Discuss / Widget-to-Chat Button ────────────────────────────────────────── */
.ema-discuss-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--ema-font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 3px 9px;
  border: 1px solid var(--ema-amber-dim);
  border-radius: 2px;
  background: var(--ema-amber-glow);
  color: var(--ema-amber);
  cursor: pointer;
  transition: all 0.15s;
  white-space: nowrap;
}

.ema-discuss-btn:hover {
  background: var(--ema-amber);
  border-color: var(--ema-amber);
  color: #000;
}

.ema-discuss-btn:hover svg { stroke: #000; }
.ema-discuss-btn svg { stroke: var(--ema-amber); transition: stroke 0.15s; }

/* ── Widget-chat seed banner ─────────────────────────────────────────────────── */
.ema-seed-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--ema-amber-glow);
  border: 1px solid var(--ema-amber-dim);
  border-radius: var(--ema-radius);
  font-family: var(--ema-font-ui);
  font-size: 11.5px;
  color: var(--ema-amber);
  animation: ema-fade-in 0.2s ease;
}

/* ── Floating chat modal overlay ─────────────────────────────────────────────── */
.ema-chat-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.75);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 99999;
  padding: 20px;
  backdrop-filter: blur(4px);
  animation: ema-fade-in 0.15s ease;
}

.ema-chat-modal {
  position: relative;
  width: 100%;
  max-width: 680px;
  border-radius: var(--ema-radius-lg);
  overflow: hidden;
  box-shadow: 0 24px 64px rgba(0,0,0,0.8);
  animation: ema-slide-up 0.2s ease;
}

@keyframes ema-slide-up {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

.ema-chat-modal-close {
  position: absolute;
  top: 10px;
  right: 12px;
  z-index: 10;
  width: 28px;
  height: 28px;
  background: rgba(0,0,0,0.4);
  border: 1px solid var(--ema-border);
  border-radius: 50%;
  font-size: 16px;
  line-height: 1;
  color: var(--ema-text-dim);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s;
}

.ema-chat-modal-close:hover { background: var(--ema-down-bg); color: var(--ema-down); border-color: var(--ema-down); }

/* Admin template button */
.ema-tpl-btn {
  font-size: 11px !important;
  padding: 3px 8px !important;
  height: auto !important;
}

/* ── Live Map (MapLibre, Phase 3) ─────────────────────────────────────────────
 * .ema-widget--live_map is the shortcode container (has an inline height
 * style from the [ema_live_map height="..."] attribute). Everything below
 * fills it.
 * ──────────────────────────────────────────────────────────────────────── */
.ema-widget--live_map {
  position: relative;
  overflow: hidden;
  padding: 0;
  min-height: 420px;
}

/* NOTE: this class is added to the SAME element as .ema-widget--live_map
 * (see energymaster-map.js), not a separate child wrapper — so it must not
 * redeclare `position`. That element already has `position: relative` from
 * .ema-widget--live_map above, which is what its absolutely-positioned
 * children (.ema-map-canvas, sidebar, status, panel) need to size against.
 * Setting `position: absolute` here used to win the cascade (same
 * specificity, declared later) and rip the whole widget out of its
 * containing frame's flex/grid layout and out of normal page flow. */
.ema-map-root { display: flex; }

/* MapLibre GL adds its own class "maplibregl-map" to this same element
 * (see maplibre-gl.js's _setupContainer(), which does
 * this._container.classList.add("maplibregl-map")). Its bundled CSS sets
 * .maplibregl-map { position: relative; } with no inset — same specificity
 * as a plain .ema-map-canvas rule, so whichever stylesheet prints later in
 * <head> wins the cascade. Because maplibre-gl.css is enqueued after
 * ema-frontend's own stylesheet (see Assets::maybe_enqueue_live_map(),
 * called after enqueue_frontend() registers this file), MapLibre's rule was
 * winning and collapsing this element back out of the absolute/inset:0 fill
 * it needs — which left the canvas with no real size while the
 * absolutely-positioned sidebar/status/legend (unaffected siblings)
 * rendered fine. Scoping to two classes (0,2,0) beats MapLibre's one-class
 * rule (0,1,0) regardless of enqueue order, so this no longer depends on
 * being lucky about stylesheet print order. */
.ema-widget--live_map .ema-map-canvas { position: absolute; inset: 0; }

.ema-map-canvas .maplibregl-popup-content {
  background: var(--ema-bg-panel);
  color: var(--ema-text);
  border: 1px solid var(--ema-border);
}

.ema-map-sidebar {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 5;
  width: 168px;
  max-height: calc(100% - 20px);
  overflow-y: auto;
  background: rgba(15, 18, 24, 0.92);
  border: 1px solid var(--ema-border);
  border-radius: var(--ema-radius);
  padding: 10px;
  font-family: var(--ema-font-mono);
  backdrop-filter: blur(4px);
}

.ema-map-sidebar-title {
  font-family: var(--ema-font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ema-text-label);
  margin-bottom: 6px;
}

.ema-map-filter-row {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 10.5px;
  color: var(--ema-text);
  padding: 2px 0;
  cursor: pointer;
}

.ema-map-legend-row {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 9.5px;
  color: var(--ema-text-dim);
  padding: 1.5px 0;
}

.ema-map-legend-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-block;
}

/* Pipelines/powerlines render as map lines, not points, so their legend
   swatch is a short bar rather than the round dot used for fuel types
   above — reads correctly as "this is a line on the map", not a pin. */
.ema-map-legend-line {
  width: 14px;
  height: 3px;
  border-radius: 1.5px;
  flex-shrink: 0;
  display: inline-block;
}

.ema-map-grid-status {
  font-family: var(--ema-font-mono);
  font-size: 9px;
  color: var(--ema-text-dim);
  padding: 2px 0 4px;
  line-height: 1.4;
}

.ema-map-grid-legend { margin-top: 2px; }

.ema-map-legend-note {
  font-family: var(--ema-font-mono);
  font-size: 9px;
  color: var(--ema-text-dim);
  font-style: italic;
  padding-top: 2px;
}

.ema-map-grid-mix-title {
  font-family: var(--ema-font-mono);
  font-size: 8.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ema-text-label);
  margin-bottom: 6px;
}

.ema-map-grid-mix { display: flex; flex-direction: column; gap: 5px; }

.ema-map-grid-mix-row {
  display: grid;
  grid-template-columns: 64px 1fr 30px;
  align-items: center;
  gap: 6px;
}

.ema-map-grid-mix-label {
  font-size: 9.5px;
  color: var(--ema-text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ema-map-grid-mix-bar-track {
  height: 6px;
  background: var(--ema-bg-input);
  border-radius: 3px;
  overflow: hidden;
}

.ema-map-grid-mix-bar-fill {
  height: 100%;
  border-radius: 3px;
  transition: width 300ms ease;
}

.ema-map-grid-mix-pct {
  font-family: var(--ema-font-mono);
  font-size: 9.5px;
  color: var(--ema-text);
  text-align: right;
}

.ema-map-status {
  position: absolute;
  bottom: 10px;
  left: 10px;
  z-index: 5;
  background: rgba(15, 18, 24, 0.92);
  border: 1px solid var(--ema-border);
  border-radius: var(--ema-radius);
  padding: 5px 10px;
  font-family: var(--ema-font-mono);
  font-size: 10px;
  color: var(--ema-text-dim);
}

.ema-map-error {
  padding: 24px;
  text-align: center;
  color: var(--ema-text-dim);
  font-family: var(--ema-font-mono);
  font-size: 12px;
}

.ema-map-panel {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 6;
  width: 260px;
  max-height: calc(100% - 20px);
  overflow-y: auto;
  background: var(--ema-bg-card);
  border: 1px solid var(--ema-border);
  border-radius: var(--ema-radius-lg);
  padding: 14px;
  box-shadow: var(--ema-shadow);
}

.ema-map-panel--hidden { display: none; }

.ema-map-panel-close {
  position: absolute;
  top: 8px;
  right: 8px;
  background: none;
  border: none;
  color: var(--ema-text-dim);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  padding: 4px;
}
.ema-map-panel-close:hover { color: var(--ema-down); }

.ema-map-panel-title {
  font-family: var(--ema-font-ui);
  font-size: 15px;
  font-weight: 700;
  color: var(--ema-text-bright);
  padding-right: 20px;
}

.ema-map-panel-sub {
  font-family: var(--ema-font-mono);
  font-size: 10px;
  color: var(--ema-text-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-top: 2px;
  margin-bottom: 10px;
}

.ema-map-panel-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-bottom: 12px;
}

.ema-map-panel-grid > div { display: flex; flex-direction: column; gap: 2px; }

.ema-map-panel-label {
  font-family: var(--ema-font-mono);
  font-size: 8.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ema-text-label);
}

.ema-map-panel-grid span:last-child {
  font-family: var(--ema-font-mono);
  font-size: 11px;
  color: var(--ema-text);
}

.ema-map-run-ai {
  width: 100%;
  background: var(--ema-amber-glow);
  border: 1px solid var(--ema-amber-dim);
  color: var(--ema-amber);
  border-radius: var(--ema-radius);
  padding: 7px;
  font-family: var(--ema-font-ui);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.03em;
  cursor: pointer;
  transition: var(--ema-transition);
}
.ema-map-run-ai:hover:not(:disabled) { background: var(--ema-amber); color: #0a0c10; }
.ema-map-run-ai:disabled { opacity: 0.6; cursor: default; }

.ema-map-ai-result { margin-top: 10px; }

.ema-map-ai-risk {
  font-family: var(--ema-font-mono);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.06em;
  margin-bottom: 4px;
}

.ema-map-ai-headline {
  font-family: var(--ema-font-ui);
  font-size: 13px;
  font-weight: 600;
  color: var(--ema-text-bright);
  margin-bottom: 6px;
}

.ema-map-ai-insight {
  font-size: 11px;
  line-height: 1.5;
  color: var(--ema-text);
  margin-bottom: 8px;
}

.ema-map-ai-reco {
  font-size: 10.5px;
  line-height: 1.5;
  color: var(--ema-cyan);
  border-left: 2px solid var(--ema-cyan-dim);
  padding-left: 8px;
  margin-bottom: 4px;
}

.ema-map-ai-grid-context {
  font-family: var(--ema-font-mono);
  font-size: 9.5px;
  color: var(--ema-text-dim);
  margin-top: 8px;
  padding-top: 6px;
  border-top: 1px solid var(--ema-border-soft);
}

.ema-map-ai-error {
  font-size: 11px;
  color: var(--ema-down);
}

@media (max-width: 640px) {
  .ema-map-sidebar { width: 130px; font-size: 9px; }
  .ema-map-panel { left: 10px; right: 10px; width: auto; }
}

/* ── Price Chart (Lightweight Charts, Phase 6) ────────────────────────────────
 * .ema-widget--price_chart is the shortcode container (inline height style
 * from the [ema_price_chart height="..."] attribute). This is genuinely
 * retrieved/computed data (wp_ema_price_history) — no disclosure badge, same
 * as the ticker.
 * ──────────────────────────────────────────────────────────────────────── */
.ema-widget--price_chart {
  display: flex;
  flex-direction: column;
  padding: 10px 12px 8px;
  min-height: 280px;
}

.ema-price-chart {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  gap: 6px;
}

.ema-price-chart__toolbar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.ema-price-chart__symbol {
  font-family: var(--ema-font-mono);
  font-size: 14px;
  font-weight: 600;
  color: var(--ema-text-bright);
  letter-spacing: 0.02em;
}

.ema-price-chart__meta {
  font-size: 10px;
  color: var(--ema-text-dim);
  font-family: var(--ema-font-mono);
}

.ema-price-chart__ranges {
  display: flex;
  gap: 4px;
}

.ema-price-chart__range-btn {
  font-family: var(--ema-font-mono);
  font-size: 10.5px;
  padding: 3px 9px;
  background: var(--ema-bg-input);
  color: var(--ema-text-label);
  border: 1px solid var(--ema-border);
  border-radius: var(--ema-radius);
  cursor: pointer;
  transition: all 0.15s ease;
}

.ema-price-chart__range-btn:hover { color: var(--ema-text); border-color: var(--ema-amber-dim); }

.ema-price-chart__range-btn.is-active {
  background: var(--ema-amber-glow);
  color: var(--ema-amber);
  border-color: var(--ema-amber-dim);
}

.ema-price-chart__host {
  flex: 1;
  min-height: 180px;
  position: relative;
}

.ema-price-chart__status {
  font-size: 10px;
  color: var(--ema-text-dim);
  font-family: var(--ema-font-mono);
}

.ema-chart-error {
  font-size: 11px;
  color: var(--ema-down);
  padding: 10px;
}

/* ══════════════════════════════════════════════════════════════════════════
   Compiled Dashboard — [ema_dashboard]
   One shortcode, every currently-enabled widget, laid out as a ticker strip
   plus a two-column grid of panels — the "everything in one glanceable
   view" pattern common to real-time intelligence/terminal dashboards.
   Independently coded: no code or assets are shared with any third-party
   dashboard product.
   ══════════════════════════════════════════════════════════════════════════ */
/* ══════════════════════════════════════════════════════════════════════════
   Compiled Dashboard — [ema_dashboard]
   The "major frame": a full-viewport-width app shell, sitting below the
   site header in normal page flow (nothing here is position:fixed or
   sticky), at a standard height that adapts per device. It holds a
   pinned ticker strip, then a single scroll region containing the live
   map — full width, standard height, always the first thing in view —
   with every other enabled widget flowing automatically into a
   responsive grid beneath it. The map and that grid scroll together as
   one surface: scrolling down inside the frame carries the map up and
   out of view while the widget grid rises to fill the frame. Because
   that inner scroll region has a bounded height rather than growing to
   fit its content, the browser hands scrolling back to the page itself
   the moment the inner region hits its end — so the page keeps scrolling
   straight past the frame to reach whatever comes after it, footer
   included, with no extra plumbing required.
   Independently coded: no code or assets are shared with any third-party
   dashboard product.
   ══════════════════════════════════════════════════════════════════════════ */
.ema-page-dashboard-wrap {
  margin: 0;
  padding: 0;
  width: 100%;
}

.ema-dashboard {
  display: flex;
  flex-direction: column;
  gap: 16px;
  background: var(--ema-bg);
  padding: 16px;
  border-radius: var(--ema-radius-lg);
}

.ema-dashboard .ema-widget {
  margin: 0;
}

/* ── Full-bleed shell: breaks the whole dashboard out to viewport width ──── */
.ema-dashboard--framed {
  /* Break out of the theme's normal content-width container to span the
   * full viewport, regardless of how narrow the page's content column is.
   * Requires no ancestor to set overflow-x:hidden — true of the vast
   * majority of themes, since that would also break their own full-width
   * blocks (Gutenberg's alignfull uses this same technique). */
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  border-radius: 0;
  padding: 12px clamp(12px, 2.5vw, 32px) 24px;
  box-sizing: border-box;
  overflow-x: hidden;
}

.ema-dashboard--framed > .ema-widget--ticker {
  flex-shrink: 0; /* pinned strip at the very top, immediately below the header */
}

/* ══════════════════════════════════════════════════════════════════════════
   Frame 1 — the map, on its own, full width, standard height. Sits directly
   beneath the ticker (or the header itself if the ticker is disabled) and
   in normal page flow: nothing here is fixed/sticky or independently
   scrolling, so the page just scrolls straight past it as usual.
   ══════════════════════════════════════════════════════════════════════════ */
.ema-map-frame {
  width: 100%;
  /* Standard height that still adapts to the viewport: generous on a normal
   * desktop/laptop, capped so it doesn't dominate an ultrawide/4K monitor,
   * with a floor so it doesn't get crushed on short viewports either. */
  height: clamp(360px, 50vh, 560px);
}

.ema-map-frame .ema-widget--live_map {
  width: 100%;
  height: 100% !important; /* overrides the shortcode's own inline px height */
  min-height: 0;
}

/* ══════════════════════════════════════════════════════════════════════════
   Frame 2 — every other enabled widget, in its own full-width frame below
   the map frame, floating side by side in a grid. Shape follows Settings →
   Dashboard Grid Layout: "auto" (responsive, min. 3 columns) or "fixed"
   (admin-chosen column count, optionally capped to a row count).

   Every panel is pinned to one uniform row height (--ema-panel-height)
   regardless of how much its own widget has to show — a widget with a
   short reading (e.g. Prediction Window) sits at exactly the same height
   as one with a long one (e.g. Energy News Digest), so panels line up and
   float neatly side by side instead of one tall widget stretching the
   whole row to match it. Anything that doesn't fit scrolls inside its own
   panel — the widget's header (title + LIVE badge + toolbar) stays pinned
   in view via position:sticky while the body scrolls beneath it, so you
   never lose track of which widget you're scrolled into.
   ══════════════════════════════════════════════════════════════════════════ */
.ema-widgets-frame {
  width: 100%;
}

.ema-widgets-grid {
  display: grid;
  gap: 16px;
  align-items: stretch; /* every panel in a row fills the same uniform row height */
}

.ema-widget-panel {
  min-width: 0;
  min-height: 0;    /* grid-item gotcha: without this, a tall widget's own
                        content forces the row taller regardless of
                        grid-auto-rows / stretch below */
  height: 100%;
  overflow: hidden;  /* the panel itself never scrolls or shows a scrollbar —
                         its widget does (see below); this just stops the
                         panel's own box being pushed taller than the row
                         track by its content's intrinsic size */
}

/* The widget itself is the scroll region — pinned to fill its panel
 * exactly (overriding whatever px height, if any, the shortcode gave it
 * inline), with its own header staying put via position:sticky while
 * everything below it scrolls. Works for every widget type the same way,
 * regardless of how many sibling elements it renders after its header. */
.ema-widgets-grid .ema-widget-panel > .ema-widget {
  height: 100% !important;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
  scrollbar-color: var(--ema-border) transparent;
}

.ema-widgets-grid .ema-widget-panel > .ema-widget::-webkit-scrollbar       { width: 6px; }
.ema-widgets-grid .ema-widget-panel > .ema-widget::-webkit-scrollbar-track { background: transparent; }
.ema-widgets-grid .ema-widget-panel > .ema-widget::-webkit-scrollbar-thumb { background: var(--ema-border); border-radius: 3px; }

.ema-widgets-grid .ema-widget-header {
  position: sticky;
  top: 0;
  z-index: 2; /* stays above the content scrolling past beneath it */
}

/* ── Auto mode: free-floating, responsive — never fewer than 3 columns on
 * a normal desktop/laptop width. Grows past 3 on very wide monitors and
 * only drops below 3 on tablet/phone, where a hard 3-up grid stops being
 * usable regardless of what the frame width technically allows. ────────── */
.ema-widgets-grid--auto {
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: var(--ema-panel-height);
}

@media (min-width: 1400px) {
  /* Enough room to let extra columns appear on their own rather than
   * stretching 3 wide panels thinner and thinner as the screen grows. */
  .ema-widgets-grid--auto {
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  }
}

/* ── Fixed mode: exact admin-chosen column count via --ema-grid-cols. ───── */
.ema-widgets-grid--fixed {
  grid-template-columns: repeat(var(--ema-grid-cols, 3), 1fr);
  grid-auto-rows: var(--ema-panel-height);
}

/* Fixed mode + a row cap chosen by the admin (--ema-grid-rows > 0): give
 * every row the same uniform height (already true for every mode now) and
 * constrain the frame to exactly that many visible rows, letting it scroll
 * internally for any widgets beyond it — a literal columns × rows grid
 * "window" rather than an ever-growing page. Per-panel scrolling above
 * still applies inside each of those rows exactly the same way. */
.ema-widgets-grid--rows-capped {
  max-height: calc(var(--ema-grid-rows, 2) * var(--ema-panel-height) + (var(--ema-grid-rows, 2) - 1) * 16px);
  overflow-y: auto;
  overflow-x: hidden;
  padding-right: 4px; /* keeps the scrollbar from touching widget borders */
  scrollbar-width: thin;
  scrollbar-color: var(--ema-border) transparent;
}

.ema-widgets-grid--rows-capped::-webkit-scrollbar       { width: 6px; }
.ema-widgets-grid--rows-capped::-webkit-scrollbar-track { background: transparent; }
.ema-widgets-grid--rows-capped::-webkit-scrollbar-thumb { background: var(--ema-border); border-radius: 3px; }

@media (max-width: 1100px) {
  /* Tablet: neither mode's column count is appropriate at this width —
   * override both down to 2 so panels stay readable. */
  .ema-widgets-grid--auto,
  .ema-widgets-grid--fixed {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 900px) {
  /* A pinned-height map frame is still worthwhile on a phone; fixed-height,
   * internally-scrolling widget panels are not — drop the uniform row
   * height and per-panel scroll entirely and fall back to a normal stack
   * driven by the page's own scroll, the more usable pattern on small
   * screens and touch devices. Nested scroll regions are fiddly with a
   * thumb, and the screen is narrow enough that only one column fits
   * anyway, so there's no row of neighbours left to line heights up with. */
  .ema-map-frame {
    height: 320px;
  }
  .ema-widgets-grid--auto,
  .ema-widgets-grid--fixed {
    grid-template-columns: 1fr;
    grid-auto-rows: auto;
  }
  .ema-widget-panel {
    height: auto;
    overflow: visible;
  }
  .ema-widgets-grid .ema-widget-panel > .ema-widget {
    height: auto !important;
    overflow: visible;
  }
  .ema-widgets-grid .ema-widget-header {
    position: static;
  }
  .ema-widgets-grid--rows-capped {
    max-height: none;
    overflow-y: visible;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   Widget fullscreen expand/collapse — every widget panel and the Live Map
   get a small expand icon; clicking it (or the Live Map / Price Chart's
   own copy, added from their own scripts via window.EMAWidget) blows that
   one widget up to a full-viewport view over a dim backdrop, with the icon
   swapping to a "back to dashboard" collapse glyph. The widget is never
   reparented — only a class is toggled — so a live MapLibre canvas or
   chart instance survives the transition; both already watch their own
   container's size and resize themselves accordingly.
   ══════════════════════════════════════════════════════════════════════════ */
.ema-widget-expand-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 1px solid var(--ema-border);
  border-radius: var(--ema-radius);
  background: var(--ema-bg-panel);
  color: var(--ema-text-dim);
  cursor: pointer;
  transition: color var(--ema-transition), border-color var(--ema-transition);
}

.ema-widget-expand-btn svg { width: 13px; height: 13px; }

.ema-widget-expand-btn:hover,
.ema-widget-expand-btn[aria-pressed="true"] {
  color: var(--ema-amber);
  border-color: var(--ema-amber-dim);
}

/* Docked inline in a widget's own sticky header (heatmap, prediction,
 * news digest, chat, alert feed, futures curve, correlation matrix, africa
 * board, generic widget) instead of floating over the content. */
.ema-widget-header-right .ema-widget-expand-btn {
  position: static;
  width: 20px;
  height: 20px;
}

/* Price Chart has its own toolbar row (symbol + meta) to dock into instead
 * of floating over the chart canvas — see energymaster-chart.js. */
.ema-price-chart__toolbar > .ema-widget-expand-btn {
  position: static;
  width: 20px;
  height: 20px;
  margin-left: auto; /* toolbar is flex + gap; this pins it to the far right
                         without disturbing the symbol/meta's own spacing */
}

/* The Live Map has no header row and its top corners are already spoken
 * for (MapLibre's own zoom/compass control top-right, the click-a-facility
 * panel top-right, the layers/legend sidebar top-left, the status strip
 * bottom-left) — bottom-right is the one free corner. See
 * energymaster-map.js. */
.ema-widget-expand-btn--map-corner {
  top: auto;
  bottom: 10px;
  right: 10px;
}

/* ══════════════════════════════════════════════════════════════════════════
   Manual refresh button — every widget gets one: docked into the shared
   header (see widgetHeader() in energymaster.js) for most widgets, or
   placed by hand where a widget has no shared header to hook into (the
   Ticker's compact strip, the Live Map's corner, the Price Chart's own
   toolbar). Clicking it re-runs that exact widget's own fetch on demand,
   the same cycle its auto-refresh timer and error-retry already use.
   ══════════════════════════════════════════════════════════════════════════ */
.ema-widget-refresh-btn {
  position: relative;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 1px solid var(--ema-border);
  border-radius: var(--ema-radius);
  background: var(--ema-bg-panel);
  color: var(--ema-text-dim);
  cursor: pointer;
  transition: color var(--ema-transition), border-color var(--ema-transition);
}

.ema-widget-refresh-btn svg { width: 13px; height: 13px; }

.ema-widget-refresh-btn:hover { color: var(--ema-amber); border-color: var(--ema-amber-dim); }

.ema-widget-refresh-btn:disabled { cursor: default; }

.ema-widget-refresh-btn.is-refreshing svg { animation: ema-spin 0.7s linear infinite; }

/* Docked inline in a widget's own sticky header, next to the expand button. */
.ema-widget-header-right .ema-widget-refresh-btn {
  width: 20px;
  height: 20px;
}

/* Ticker — no header row to dock into; pinned to the strip's right edge,
 * floating over the scrolling track. See energymaster.js initTicker(). */
.ema-ticker-has-refresh { position: relative; }

.ema-ticker-refresh-btn {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  background: var(--ema-bg);
  box-shadow: -10px 0 10px 4px var(--ema-bg); /* fade the track out from under it */
}

/* Live Map — docked just above the expand button in the one free corner. */
.ema-widget-refresh-btn--map-corner {
  position: absolute;
  bottom: 42px;
  right: 10px;
}

/* Price Chart has its own toolbar row (symbol + meta) to dock into. */
.ema-price-chart__refresh-btn {
  width: 20px;
  height: 20px;
  margin-left: auto; /* pins refresh+expand to the far right without disturbing symbol/meta spacing */
}
.ema-price-chart__toolbar > .ema-widget-expand-btn { margin-left: 0; }

.ema-widget-fullscreen-backdrop {
  position: fixed;
  inset: 0;
  z-index: 99998;
  background: rgba(0, 0, 0, 0.75);
  animation: ema-fullscreen-fade 160ms ease;
}

@keyframes ema-fullscreen-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

body.ema-widget-fullscreen-open {
  overflow: hidden; /* lock page scroll behind the backdrop */
}

.ema-widget--fullscreen {
  position: fixed !important;
  inset: clamp(8px, 3vh, 40px) clamp(8px, 3vw, 60px) !important;
  width: auto !important;
  height: auto !important;
  max-width: none !important;
  max-height: none !important;
  margin: 0 !important;
  z-index: 99999 !important;
  overflow-y: auto !important;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}

/* Same rule, written specifically to out-specificity the grid's own
 * `.ema-widgets-grid .ema-widget-panel > .ema-widget { height:100%
 * !important }` rule further up — two `!important` declarations are
 * resolved by specificity, not source order, so the plain class selector
 * above isn't enough inside the grid on its own. */
.ema-widgets-grid .ema-widget-panel > .ema-widget.ema-widget--fullscreen {
  position: fixed !important;
  inset: clamp(8px, 3vh, 40px) clamp(8px, 3vw, 60px) !important;
  width: auto !important;
  height: auto !important;
  max-width: none !important;
  max-height: none !important;
  margin: 0 !important;
  overflow-y: auto !important;
}

/* Same reasoning again for the Live Map's own `.ema-map-frame
 * .ema-widget--live_map { height: 100% !important }` rule further up. */
.ema-map-frame .ema-widget--live_map.ema-widget--fullscreen {
  position: fixed !important;
  inset: clamp(8px, 3vh, 40px) clamp(8px, 3vw, 60px) !important;
  width: auto !important;
  height: auto !important;
  max-width: none !important;
  max-height: none !important;
  margin: 0 !important;
}

.ema-dashboard-empty {
  font-family: var(--ema-font-mono);
  font-size: 12px;
  color: var(--ema-text-dim);
  background: var(--ema-bg-panel);
  border: 1px dashed var(--ema-border);
  border-radius: var(--ema-radius);
  padding: 24px;
  text-align: center;
}

/* ── Disabled-widget notice (admins/editors only) ─────────────────────────── */
.ema-widget-disabled-notice {
  font-family: var(--ema-font-mono);
  font-size: 11px;
  color: var(--ema-text-dim);
  background: var(--ema-bg-panel);
  border: 1px dashed var(--ema-border);
  border-radius: var(--ema-radius);
  padding: 14px 16px;
  margin: 8px 0;
}

/* ============================================================================
   Access Control — "Sign in to chat" prompt
   Two markup shapes share these rules: Shortcodes::login_required_notice()
   (server-rendered, for [ema_chat] / [ema_analysis_hub]) wraps its children
   in .ema-widget-login-required; buildLoginRequiredFsPanel() in
   energymaster.js reuses .ema-fs-chat-panel(--login-required) so it inherits
   the normal Analyze-panel positioning/animation and only needs its own
   inner spacing below.
   ============================================================================ */
.ema-widget-login-required,
.ema-fs-chat-panel--login-required {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-align: center;
  padding: 24px 20px;
  background: var(--ema-bg-panel);
  border: 1px solid var(--ema-border);
  border-radius: var(--ema-radius);
}

.ema-login-required__icon {
  font-size: 22px;
  opacity: 0.85;
}

.ema-login-required__text {
  font-family: var(--ema-font-mono);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ema-text-dim);
  max-width: 30ch;
  margin: 0;
}

.ema-login-required__btn {
  display: inline-block;
  margin-top: 4px;
  padding: 8px 20px;
  font-family: var(--ema-font-mono);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ema-bg);
  background: var(--ema-amber);
  border-radius: var(--ema-radius);
  text-decoration: none;
  transition: opacity 0.15s ease;
}

.ema-login-required__btn:hover,
.ema-login-required__btn:focus {
  opacity: 0.85;
  color: var(--ema-bg);
}

/* ============================================================================
   Widget-Chat Interconnection — Fullscreen Analysis Panel
   Deliberately positioned with `position: fixed` relative to the viewport
   (not nested inside the widget) — several widgets rebuild their entire DOM
   on a periodic refresh, which would otherwise wipe an in-progress
   conversation. See the JS comment in exitWidgetFullscreen() for the full
   reasoning. Anchored to the exact same inset .ema-widget--fullscreen uses
   (clamp(8px,3vh,40px) / clamp(8px,3vw,60px)) so it always lines up with
   the fullscreen widget's edges, and sits one z-index layer above it
   (99999) so it's never occluded.
   ============================================================================ */

.ema-fs-analyze-toggle {
  position: fixed;
  /* The widget's own sticky header (title + refresh + expand/collapse
   * buttons) is ~41px tall (10px padding + 20px button + 10px padding +
   * 1px border) and pins itself to this exact same top-right inset, so a
   * +14px offset alone sat the pill almost directly on top of it. Clearing
   * the header height (plus a small gap) keeps the two visually stacked
   * instead of overlapping. */
  top: calc(clamp(8px, 3vh, 40px) + 54px);
  right: calc(clamp(8px, 3vw, 60px) + 14px);
  z-index: 100001;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--ema-font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 8px 15px;
  border: 1px solid var(--ema-amber-dim);
  border-radius: 999px;
  background: var(--ema-bg-card);
  color: var(--ema-amber);
  cursor: pointer;
  box-shadow: var(--ema-shadow);
  transition: all 0.15s;
}

.ema-fs-analyze-toggle:hover,
.ema-fs-analyze-toggle.is-active {
  background: var(--ema-amber);
  border-color: var(--ema-amber);
  color: #000;
}

.ema-fs-chat-panel {
  position: fixed;
  top: clamp(8px, 3vh, 40px);
  bottom: clamp(8px, 3vh, 40px);
  right: clamp(8px, 3vw, 60px);
  width: min(380px, 92vw);
  z-index: 100000;
  display: flex;
  flex-direction: column;
  background: var(--ema-bg-panel);
  border: 1px solid var(--ema-border);
  border-radius: var(--ema-radius-lg);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
  transform: translateX(calc(100% + 24px));
  opacity: 0;
  pointer-events: none;
  transition: transform 220ms ease, opacity 220ms ease;
  overflow: hidden;
}

.ema-fs-chat-panel.is-open {
  transform: translateX(0);
  opacity: 1;
  pointer-events: auto;
}

.ema-fs-chat-panel__header {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--ema-border-soft);
  background: var(--ema-bg-card);
  flex-shrink: 0;
}

.ema-fs-chat-panel__title {
  font-family: var(--ema-font-ui);
  font-weight: 700;
  font-size: 13px;
  color: var(--ema-text-bright);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.ema-fs-chat-panel__actions {
  display: flex;
  align-items: center;
  gap: 6px;
}

.ema-fs-chat-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--ema-font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 4px 8px;
  border: 1px solid var(--ema-border);
  border-radius: 2px;
  background: transparent;
  color: var(--ema-text-dim);
  cursor: pointer;
  transition: all 0.15s;
  white-space: nowrap;
}

.ema-fs-chat-btn:hover:not(:disabled) { border-color: var(--ema-amber-dim); color: var(--ema-amber); }
.ema-fs-chat-btn:disabled { opacity: 0.5; cursor: not-allowed; }

.ema-fs-chat-panel__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border: none;
  border-radius: 2px;
  background: transparent;
  color: var(--ema-text-dim);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  transition: all 0.15s;
  flex-shrink: 0;
}

.ema-fs-chat-panel__close:hover { background: var(--ema-border-soft); color: var(--ema-text-bright); }

.ema-fs-chat-imported { flex-shrink: 0; }

.ema-fs-chat-imported__item {
  font-family: var(--ema-font-mono);
  font-size: 10px;
  color: var(--ema-cyan);
  background: var(--ema-cyan-dim);
  padding: 5px 12px;
  border-bottom: 1px solid var(--ema-border-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Thread picker popover — opened from the fullscreen panel's Import button
 * (and reused, via openThreadPicker(), anywhere else a thread needs picking). */
.ema-thread-picker {
  position: absolute;
  top: calc(100% + 4px);
  right: 12px;
  width: 260px;
  max-height: 280px;
  overflow-y: auto;
  background: var(--ema-bg-card);
  border: 1px solid var(--ema-border);
  border-radius: var(--ema-radius);
  box-shadow: var(--ema-shadow);
  z-index: 100002;
  animation: ema-fade-in 0.15s ease;
}

.ema-thread-picker__row {
  display: flex;
  align-items: center;
  gap: 2px;
  width: 100%;
  border-bottom: 1px solid var(--ema-border-soft);
}

.ema-thread-picker__row:last-child { border-bottom: none; }

.ema-thread-picker__pick {
  display: flex;
  flex: 1;
  min-width: 0;
  flex-direction: column;
  gap: 2px;
  padding: 8px 12px;
  border: none;
  background: transparent;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s;
}

.ema-thread-picker__pick:hover { background: var(--ema-amber-glow); }

.ema-thread-picker__title {
  font-family: var(--ema-font-ui);
  font-size: 12px;
  font-weight: 600;
  color: var(--ema-text-bright);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

.ema-thread-picker__desc {
  font-family: var(--ema-font-ui);
  font-size: 11px;
  color: var(--ema-text-dim);
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.ema-thread-picker__meta {
  font-family: var(--ema-font-mono);
  font-size: 10px;
  color: var(--ema-text-dim);
  text-transform: capitalize;
}

.ema-thread-picker__delete {
  flex-shrink: 0;
  border: none;
  background: transparent;
  color: var(--ema-text-dim);
  cursor: pointer;
  font-size: 13px;
  padding: 4px 6px;
  margin-right: 6px;
  border-radius: 2px;
  transition: all 0.15s;
}

.ema-thread-picker__delete:hover { color: var(--ema-down); background: var(--ema-down-bg); }

.ema-thread-picker__empty {
  padding: 16px 12px;
  font-family: var(--ema-font-mono);
  font-size: 11px;
  color: var(--ema-text-dim);
  text-align: center;
}

/* Export details modal — Title + Description, opened from the fullscreen
 * panel's Export button (see promptExportDetails() in energymaster.js).
 * Reuses the same overlay convention as .ema-chat-modal-overlay. */
.ema-export-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.75);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100010;
  padding: 20px;
  backdrop-filter: blur(4px);
  animation: ema-fade-in 0.15s ease;
}

.ema-export-modal {
  width: 100%;
  max-width: 360px;
  background: var(--ema-bg-panel);
  border: 1px solid var(--ema-border);
  border-radius: var(--ema-radius-lg);
  box-shadow: 0 24px 64px rgba(0,0,0,0.8);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  animation: ema-slide-up 0.2s ease;
}

.ema-export-modal__title {
  font-family: var(--ema-font-ui);
  font-size: 14px;
  font-weight: 700;
  color: var(--ema-text-bright);
  margin-bottom: 6px;
}

.ema-export-modal__label {
  font-family: var(--ema-font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ema-text-label);
  margin-top: 8px;
}

.ema-export-modal__input,
.ema-export-modal__textarea {
  width: 100%;
  font-family: var(--ema-font-ui);
  font-size: 13px;
  color: var(--ema-text);
  background: var(--ema-bg);
  border: 1px solid var(--ema-border);
  border-radius: var(--ema-radius);
  padding: 8px 10px;
  resize: vertical;
}

.ema-export-modal__input:focus,
.ema-export-modal__textarea:focus {
  outline: none;
  border-color: var(--ema-amber-dim);
}

.ema-export-modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 14px;
}

.ema-export-modal__btn {
  font-family: var(--ema-font-mono);
  font-size: 12px;
  font-weight: 600;
  padding: 7px 16px;
  border-radius: var(--ema-radius);
  cursor: pointer;
  transition: opacity 0.15s ease;
}

.ema-export-modal__btn--cancel {
  background: transparent;
  color: var(--ema-text-dim);
  border: 1px solid var(--ema-border);
}

.ema-export-modal__btn--save {
  background: var(--ema-amber);
  color: var(--ema-bg);
  border: none;
}

.ema-export-modal__btn:hover { opacity: 0.85; }

@media (max-width: 640px) {
  .ema-fs-chat-panel {
    top: auto;
    bottom: 0;
    left: 0;
    right: 0;
    width: auto;
    height: 62vh;
    border-radius: var(--ema-radius-lg) var(--ema-radius-lg) 0 0;
    transform: translateY(100%);
  }
  .ema-fs-chat-panel.is-open { transform: translateY(0); }
  .ema-fs-analyze-toggle {
    top: auto;
    bottom: calc(clamp(8px, 3vh, 40px) + 14px);
  }
}

/* ============================================================================
   Analysis Hub — the "central widget"
   Lists saved threads (exported from any widget's fullscreen panel above),
   lets the user pick 2+, and shows the AI's cross-widget synthesis. Reuses
   .ema-chat-messages / .ema-chat-bubble / .ema-mindset / .ema-widget__loader
   from elsewhere in this file for the follow-up chat and result rendering.
   ============================================================================ */

.ema-hub-body { padding: 4px 14px 16px; }

.ema-hub-empty {
  font-family: var(--ema-font-mono);
  font-size: 12px;
  color: var(--ema-text-dim);
  text-align: center;
  line-height: 1.6;
  padding: 32px 20px;
  border: 1px dashed var(--ema-border);
  border-radius: var(--ema-radius);
}

.ema-hub-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 12px;
}

.ema-hub-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border: 1px solid var(--ema-border-soft);
  border-radius: var(--ema-radius);
  background: var(--ema-bg-card);
  cursor: pointer;
  transition: border-color 0.15s;
}

.ema-hub-row:hover { border-color: var(--ema-amber-dim); }
.ema-hub-row input[type="checkbox"] { flex-shrink: 0; accent-color: var(--ema-amber); width: 15px; height: 15px; cursor: pointer; }
.ema-hub-row__main { flex: 1; min-width: 0; }

.ema-hub-row__title {
  font-family: var(--ema-font-ui);
  font-size: 13px;
  font-weight: 600;
  color: var(--ema-text-bright);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ema-hub-row__desc {
  font-family: var(--ema-font-ui);
  font-size: 11px;
  color: var(--ema-text-dim);
  line-height: 1.3;
  margin-top: 2px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.ema-hub-row__meta {
  font-family: var(--ema-font-mono);
  font-size: 10px;
  color: var(--ema-text-dim);
  text-transform: capitalize;
  margin-top: 2px;
}

.ema-hub-row__delete {
  flex-shrink: 0;
  border: none;
  background: transparent;
  color: var(--ema-text-dim);
  cursor: pointer;
  font-size: 13px;
  padding: 4px 6px;
  border-radius: 2px;
  transition: all 0.15s;
}

.ema-hub-row__delete:hover { color: var(--ema-down); background: var(--ema-down-bg); }

.ema-hub-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.ema-hub-hint {
  font-family: var(--ema-font-mono);
  font-size: 10px;
  color: var(--ema-text-dim);
}

.ema-hub-synth-btn {
  font-family: var(--ema-font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 8px 18px;
  border: 1px solid var(--ema-amber-dim);
  border-radius: 2px;
  background: var(--ema-amber-glow);
  color: var(--ema-amber);
  cursor: pointer;
  transition: all 0.15s;
  white-space: nowrap;
}

.ema-hub-synth-btn:hover:not(:disabled) { background: var(--ema-amber); border-color: var(--ema-amber); color: #000; }
.ema-hub-synth-btn:disabled { opacity: 0.4; cursor: not-allowed; }

.ema-hub-result:empty { display: none; }

.ema-hub-followup {
  margin-top: 14px;
  border-top: 1px solid var(--ema-border-soft);
  padding-top: 10px;
}

.ema-hub-followup-messages {
  max-height: 240px;
  overflow-y: auto;
  margin-bottom: 8px;
  padding-right: 2px;
}

.ema-hub-followup .ema-chat-input-area {
  padding: 0;
  background: transparent;
  border-top: none;
}

/* ── Premium AI Council: 3-slider model selection panel ──────────────────────
 * Sits as an ordinary (non-flex-1) child between the messages list and the
 * input area on every chat surface — chat terminal, Analyze panel, Hub
 * synthesize action, and Hub follow-up — collapsed to just the toggle row
 * by default so it costs almost no layout space until opened. */
.ema-premium-panel {
  flex-shrink: 0;
  border-top: 1px solid var(--ema-border);
  background: var(--ema-bg-panel);
}

.ema-premium-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 8px 16px;
  background: transparent;
  border: none;
  font-family: var(--ema-font-mono);
  font-size: 10.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ema-text-dim);
  cursor: pointer;
  transition: color var(--ema-transition);
}

.ema-premium-toggle:hover,
.ema-premium-toggle.is-open { color: var(--ema-amber); }

.ema-premium-icon { font-size: 12px; line-height: 1; }

.ema-premium-badge {
  margin-left: auto;
  font-family: var(--ema-font-ui);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--ema-amber-glow);
  border: 1px solid var(--ema-amber-dim);
  color: var(--ema-amber);
  white-space: nowrap;
}

.ema-premium-panel--locked .ema-premium-toggle .ema-premium-badge {
  background: transparent;
  border-color: var(--ema-border);
  color: var(--ema-text-dim);
}

.ema-premium-sliders {
  padding: 2px 16px 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-height: 260px;
  overflow-y: auto;
}

.ema-slider-row label {
  display: block;
  font-family: var(--ema-font-mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ema-text-dim);
  margin-bottom: 5px;
}

.ema-premium-slider {
  width: 100%;
  height: 4px;
  accent-color: var(--ema-amber);
  cursor: pointer;
}

.ema-slider-scale {
  display: flex;
  justify-content: space-between;
  font-family: var(--ema-font-ui);
  font-size: 10px;
  color: var(--ema-text-dim);
  margin-top: 3px;
}

.ema-premium-readout {
  font-family: var(--ema-font-mono);
  font-size: 11px;
  color: var(--ema-amber);
  padding-top: 8px;
  border-top: 1px dashed var(--ema-border);
  word-break: break-word;
}

.ema-premium-upsell {
  padding: 2px 16px 14px;
  font-family: var(--ema-font-ui);
  font-size: 12px;
  line-height: 1.5;
  color: var(--ema-text-dim);
}

/* "via <model(s)>" caption appended under an AI response that used the
 * Premium AI Council, in either single- or council-mode. */
.ema-premium-used {
  margin-top: 6px;
  font-family: var(--ema-font-mono);
  font-size: 10px;
  letter-spacing: 0.02em;
  color: var(--ema-amber);
  opacity: 0.85;
}
