/* Keep results content from scrolling sideways. Plotly wrappers carry overflow:visible
   !important (plotly-overrides.css, so unified hover tooltips aren't clipped), which lets a
   chart's angled axis labels / wide tooltips spill past their card and drag a horizontal
   scrollbar onto the page (seen on the Trading tab's two-up charts, #7). Clip horizontal
   overflow at the results body: `clip` (not `hidden`/`auto`) removes the spill without
   establishing a scroll container, so the sticky results chrome above is unaffected. Vertical
   overflow stays visible so nothing is cut off top/bottom. */
.results-content-full {
  overflow-x: clip;
}

/* Let a chart mount shrink inside a flex/grid column (Bootstrap cols default to
   min-width:auto) so an initially over-measured Plotly SVG can't push its column wider than
   the track and off the card (#7). */
.results-chart-container {
  min-width: 0;
}

/* Results pipeline navigation */
.results-pipeline {
  display: flex;
  list-style: none;
  padding: 0;
  margin: 0;
  gap: 0;
}

.results-pipeline-step {
  display: flex;
  align-items: center;
  flex: 1;
  position: relative;
}

.results-pipeline-step:not(:last-child)::after {
  content: "";
  flex: 1;
  height: 2px;
  background: #dee2e6;
  margin: 0 0.5rem;
}

.results-pipeline-step.completed:not(:last-child)::after {
  background: #198754;
}

.results-pipeline-link {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  text-decoration: none;
  color: #6c757d;
  white-space: nowrap;
  padding: 0.5rem 0;
  font-size: 0.875rem;
}

.results-pipeline-link:hover {
  color: #0d6efd;
}

.results-pipeline-link .step-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  font-size: 0.8rem;
  font-weight: 600;
  background: #e9ecef;
  color: #6c757d;
  flex-shrink: 0;
}

.results-pipeline-step.active .step-icon {
  background: #0d6efd;
  color: var(--varial-white, #fff);
}

.results-pipeline-step.active .results-pipeline-link {
  color: #0d6efd;
  font-weight: 600;
}

.results-pipeline-step.completed .step-icon {
  background: #198754;
  color: var(--varial-white, #fff);
}

.results-pipeline-step.completed .results-pipeline-link {
  color: #198754;
}

.results-pipeline-step.completed.active .step-icon {
  background: #0d6efd;
  color: var(--varial-white, #fff);
}

.results-pipeline-step.completed.active .results-pipeline-link {
  color: #0d6efd;
}

.results-pipeline-link .step-label {
  display: inline;
}

@media (max-width: 576px) {
  .results-pipeline-link .step-label {
    display: none;
  }
}

.results-chart-container {
  min-height: 400px;
  width: 100%;
}

/* Loading skeleton injected into an empty chart mount before its Plotly graph draws
   (var-results-charts.js, #3835 port). Match the chart min-height so swapping the skeleton
   for the rendered chart does not jump the layout. */
.results-chart-container > .vrl-skeleton-chart {
  height: 400px;
}

/* ── Section headings ─────────────────────────────────────────────────────── */

.results-section-heading {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--varial-text);
  margin-bottom: 1rem;
}

.results-subsection-heading {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--varial-gray-600);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 0.75rem;
}

/* ── Results headline label ───────────────────────────────────────────────── */

.results-meta-label {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--varial-gray-500, #6B6763);
}

/* The shared results chrome (identity tier + sticky section tabs) now lives in
   css/pages/results-chrome.css, loaded by both Spot and VAR. VAR-only bits stay
   below. */

/* VAR results positions map (item 13) — Leaflet needs an explicit height. */
.var-results-map {
  height: 420px;
  width: 100%;
}

/* One compact-pill style for every in-card toggle (granularity, Band/Paths, capture unit,
   dispatch scenario) so the results filters read consistently (#3612). Both class hooks map
   to the same rule; ``var-pnl-tabs`` is the canonical one used across the charts. */
.nav-pills-sm .nav-link,
.var-pnl-tabs .nav-link {
  padding: 0.15rem 0.7rem;
  font-size: 0.85rem;
}

/* Positions page: pin the map alongside the scrollable position list on wide screens. */
@media (min-width: 992px) {
  .results-map-sticky {
    position: sticky;
    top: 1rem;
  }
}

/* BESS Method A vs Method B labels — colours mirror _BESS_METHOD_COLORS in the
   controller (sky = the forecast's own dispatch, violet = the independent optimiser).
   Kept as classes (not inline styles) for the CSP no-inline-style policy. */
.bess-method-pro_rata {
  color: #0EA5E9;
}

.bess-method-price_taker {
  color: #8B5CF6;
}

/* Per-position colour swatch — the background is painted by var-results-charts.js
   from the data-position-color attribute (the canonical technology colour). */
.position-color-dot {
  display: inline-block;
  width: 0.7rem;
  height: 0.7rem;
  margin-right: 0.4rem;
  border-radius: 50%;
  vertical-align: middle;
  background: var(--varial-gray-300, #CCC9C3);
}

/* ── Position accordion ───────────────────────────────────────────────────── */

.var-position-accordion-btn {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  flex-wrap: wrap;
}

/* Position definitions table — name links through to the per-position detail page. */
.var-position-link {
  color: var(--varial-text);
  text-decoration: none;
  white-space: nowrap;
}

.var-position-link:hover {
  color: var(--varial-primary, #1b3aa0);
  text-decoration: underline;
}

/* Neutral position-type tag — a sanctioned design-system chip (no raw bootstrap
   bg-*), sized to sit beside the badge-infra / badge-run-status status tokens (#3271). */
.var-position-type-badge {
  display: inline-flex;
  align-items: center;
  padding: 0 0.55em;
  height: 1.6em;
  font-size: 0.7rem;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  border-radius: 999px;
  background: var(--varial-gray-200, #e4e2dc);
  color: var(--varial-gray-700, #38352f);
}

.var-position-capacity {
  font-size: 0.8rem;
}

.var-position-metrics .results-summary-card {
  padding: 0.65rem 0.85rem;
}

/* ── Position spec table (Position Review section) ─────────────────────────── */

.var-spec-table th {
  width: 40%;
  font-weight: 500;
  color: var(--varial-gray-600);
  font-size: 0.8125rem;
  padding: 0.3rem 0.5rem;
  border-top: none;
  white-space: nowrap;
}

.var-spec-table td {
  font-size: 0.8125rem;
  padding: 0.3rem 0.5rem;
  border-top: none;
  color: var(--varial-text);
}

.var-spec-table tbody tr:not(:last-child) th,
.var-spec-table tbody tr:not(:last-child) td {
  border-bottom: 1px solid var(--varial-border);
}

.results-summary-card {
  text-align: center;
  padding: 0.75rem;
}

.results-summary-card .stat-value {
  font-size: 1.25rem;
  font-weight: 600;
}

.results-summary-card .stat-label {
  font-size: 0.8rem;
  color: #6c757d;
}

/* Headline economics folded into the annual-earnings card: render each cell as a
   bordered tile so they read as distinct metrics inside the parent card. */
.var-summary-metrics .results-summary-card {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.15rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--varial-border);
  border-radius: var(--varial-radius, 0.375rem);
  background: var(--varial-surface-muted, rgba(127, 127, 127, 0.06));
}

/* Collapsible position-description header: a full-width toggle styled like a card header,
   with a caret that flips when the panel is open. */
.var-collapse-toggle {
  color: var(--varial-text);
  font-weight: 600;
}

.var-collapse-toggle:hover,
.var-collapse-toggle:focus {
  color: var(--varial-text);
}

.var-collapse-caret {
  transition: transform 0.15s ease-in-out;
}

.var-collapse-toggle[aria-expanded="false"] .var-collapse-caret {
  transform: rotate(-90deg);
}

/* Per-position metrics matrix: keep the metric label column readable and sticky-left so
   the period columns can scroll without losing the row name. */
.var-metrics-table th[scope="row"] {
  white-space: nowrap;
}

.results-info-panel .card-body ul {
  padding-left: 1.2rem;
  margin-bottom: 0;
}

.results-info-panel .card-body li {
  margin-bottom: 0.4rem;
}

.results-breakdown-table th,
.results-breakdown-table td {
  padding: 0.4rem 0.75rem;
}

/* P&L / metrics matrices live in a `card-body p-0`, which puts the table flush to
   the card border — the first and last columns end up jammed against the edge. Give
   those edge columns a comfortable gutter, applied uniformly across header, body and
   footer rows so every row's content lines up with the same margin. */
.results-pnl-table > :not(caption) > * > *:first-child {
  padding-left: 1rem;
}

.results-pnl-table > :not(caption) > * > *:last-child {
  padding-right: 1rem;
}

/* Expandable financial-positions group (#3323): a borderless toggle that reads as
   the row's text, with a caret that rotates as its per-trade child rows expand. */
.pnl-fin-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.pnl-fin-caret {
  width: 0.9rem;
  margin-right: 0.35rem;
  font-size: 0.75rem;
  color: var(--varial-gray-500);
  transition: transform var(--varial-transition-fast, 150ms ease);
}

/* Bootstrap keeps `.collapsed` on the trigger while the target is hidden; drop it and
   the caret points down to signal the group is open. */
.pnl-fin-toggle:not(.collapsed) .pnl-fin-caret {
  transform: rotate(90deg);
}

.results-pnl-fin-child > td:first-child {
  font-size: 0.9375rem;
}

.results-pnl-fin-child {
  background-color: var(--varial-bg-subtle);
}

/* Two-tier scenario/reference-year drill-down (#3369 / #3921): the per-universe rows are
   hidden by default and revealed globally by the header's "Show scenarios" / "Show reference
   years" buttons, which toggle .scenarios-open / .refyrs-open on every metrics table. No
   per-row carets — the two header toggles drive the whole table at once, so every metric row
   opens together (var-scenario-weights.js). Reference years only show once scenarios are open. */
.results-pnl-scenario-child,
.results-pnl-refyr-child {
  display: none;
}

.results-pnl-table.scenarios-open > tbody > .results-pnl-scenario-child,
.results-pnl-table.scenarios-open > tfoot > .results-pnl-scenario-child {
  display: table-row;
}

.results-pnl-table.scenarios-open.refyrs-open > tbody > .results-pnl-refyr-child,
.results-pnl-table.scenarios-open.refyrs-open > tfoot > .results-pnl-refyr-child {
  display: table-row;
}

/* Per-universe (scenario) and per-reference-year rows read as muted, italic supporting
   detail under the position's expected row — not another primary figure to weigh. The footer
   copies (the netted Portfolio drill-down) drop the tfoot's bold so they match the body rows. */
.results-pnl-scenario-child > td,
.results-pnl-scenario-child > th,
.results-pnl-refyr-child > td,
.results-pnl-refyr-child > th {
  font-weight: 400;
}

.results-pnl-scenario-child > td,
.results-pnl-scenario-child > th {
  color: var(--varial-gray-500);
  font-style: italic;
  font-size: 0.8125rem;
}

.results-pnl-refyr-child > td,
.results-pnl-refyr-child > th {
  color: var(--varial-gray-400);
  font-style: italic;
  font-size: 0.78125rem;
}

/* Compact per-scenario weight steppers (#3369): independent number inputs so a target lands
   exactly, laid out inline with a running total. */
.scenario-weight-stepper {
  width: 6.5rem;
}

.scenario-weight-total {
  align-self: center;
  color: var(--varial-gray-500);
}

/* Comparable assets section (#3321 / #3339): metadata + diverging $k/MW·$/MWh heatmap + map. */
.cmp-swatch {
  display: inline-block;
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 2px;
  margin-right: 0.4rem;
  vertical-align: middle;
  background-color: var(--varial-text-muted, #9ca3af);
}

.cmp-duid {
  font-family: var(--bs-font-monospace);
  font-size: 0.7rem;
  line-height: 1.1;
}

.cmp-table th.cmp-q-head,
.cmp-table td.cmp-heat-cell {
  min-width: 3.4rem;
}

.cmp-heat-cell {
  font-variant-numeric: tabular-nums;
  transition: background-color 0.15s ease;
}

/* JS flips text to white on saturated (far-from-zero) cells for contrast. */
.cmp-heat-cell.cmp-heat-dark {
  color: #ffffff;
}

/* No-value heatmap cell: a muted placeholder dot (set by JS via textContent). */
.cmp-heat-cell.cmp-heat-empty {
  color: var(--varial-text-muted, #9ca3af);
}

.cmp-own-row > td {
  background-color: var(--varial-bg-subtle);
}

/* Floating per-measure note on the merged earnings chart (#3612) — a friendly badge over the
   (empty) forecast side, e.g. the curtailment "on the to-do list" message. */
.vre-chart-note {
  position: absolute;
  top: 14%;
  right: 5%;
  max-width: 16rem;
  z-index: 3;
  padding: 0.55rem 0.75rem;
  font-size: 0.8rem;
  line-height: 1.35;
  color: var(--varial-text);
  background: var(--varial-surface, #fff);
  border: 1px solid var(--varial-border);
  border-left: 3px solid var(--varial-primary, #1b3aa0);
  border-radius: var(--varial-radius, 0.375rem);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
}

.vre-chart-note .fa-circle-info {
  color: var(--varial-primary, #1b3aa0);
}

/* Cross-highlight (#3612): comparator rows are clickable to focus the matching line on the
   merged earnings chart (and back). The focused row gets a primary-tinted fill + left rule. */
.cmp-row-clickable {
  cursor: pointer;
}

.cmp-row-focus > td {
  background-color: var(--varial-primary-bg-subtle, rgba(27, 58, 160, 0.06));
}

/* One clean accent bar on the leading cell, not a rule between every column. */
.cmp-row-focus > td:first-child {
  box-shadow: inset 3px 0 0 0 var(--varial-primary, #1b3aa0);
}

.cmp-map {
  height: 420px;
  width: 100%;
}

/* Compact numeric field in the portfolio scenario-weights editor (#3369). */
.scenario-weight-input {
  width: 6rem;
}

/* NPV cell laid out on a single line (#3524): value + compact discount stepper inline,
   so the P&L row keeps one row-height rather than stacking onto two. */
.results-npv-inline {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  justify-content: flex-end;
  white-space: nowrap;
}

/* Compact numeric field in the Trading risk-limit editor (#3524). */
.risk-limit-input {
  width: 7rem;
}

/* Reversibly hidden position (#3612): a valued position the user has dropped from the
   portfolio totals. Greyed on the Positions page so it reads as excluded, while staying
   listed with an Unhide affordance. */
.var-positions-table tr.var-position-hidden td,
.var-positions-table tr.var-position-hidden th {
  opacity: 0.55;
}
.var-positions-table tr.var-position-hidden .var-position-link {
  text-decoration: line-through;
}

/* NOTE: the payoff ASX-label chip is styled entirely server-side now (a white bgcolor +
   dark text set in charts/payoff.py:attach_asx_marker), which reads on both themes. The
   former `#payoff-chart .annotation .bg { fill: #1e293b }` override was removed: it forced
   the chip dark to pair with light text, but the server had since switched to a white chip
   with dark text, so the two collided into dark-on-dark. Annotation backgrounds now honour
   their own inline bgcolor because the transparent-background rule in plotly-overrides.css
   is scoped to `.bglayer .bg` (the plot area), not every `.bg` rect. */

/* Scenario-weighting intro copy (#3369): constrain the explainer line to a comfortable
   measure. Extracted from an inline style on portfolio.html to satisfy the no-inline-styles
   rule (static/CLAUDE.md). */
.scenario-weights-intro {
  max-width: 48rem;
}

/* ── Public demo Intro engagement (#3921 v2) ──────────────────────────────────
   The demo Intro is the one un-gated VAR surface, so it does the selling. The stat cards
   get a circular technology-tinted icon bubble (mirrors selector-tile-icon) so the book
   composition reads at a glance, and the "How to read this demo" tabs get a matching lead
   icon. Tokens/classes only (no inline styles), per static/CLAUDE.md. */
.demo-stat-card {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  transition: border-color var(--varial-transition-fast, 150ms ease),
    box-shadow var(--varial-transition-fast, 150ms ease);
}

.demo-stat-card:hover {
  border-color: var(--varial-primary, #1b3aa0);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06);
}

.demo-stat-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  margin-bottom: 0.15rem;
  border-radius: 50%;
  font-size: 1rem;
  color: var(--varial-primary, #1b3aa0);
  background: var(--varial-primary-bg-subtle, rgba(27, 58, 160, 0.08));
}

.demo-howto-item {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
}

.demo-howto-icon {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.9rem;
  height: 1.9rem;
  border-radius: 50%;
  font-size: 0.85rem;
  color: var(--varial-primary, #1b3aa0);
  background: var(--varial-primary-bg-subtle, rgba(27, 58, 160, 0.08));
}

/* Live-estimate risk cells (#3369): while the user drags scenario weights, Downside and
   Return-on-risk are previewed from the single worst path, not the server's CVaR tail mean,
   so they are recomputed exactly on Save. A dotted underline signals the value is provisional. */
.risk-estimate {
  text-decoration: underline dotted;
  text-underline-offset: 0.15em;
  cursor: help;
}
