/* 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;
}

/* Make adjacent result controls read as separate, scoped decisions rather than one long
   segmented control. The small label is deliberately quieter than both the card title and the
   active choice; on phones each group can wrap as a complete unit. */
.results-control-cluster {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 0.55rem 0.8rem;
}

.results-control-group {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  min-width: 0;
}

.results-control-label {
  color: var(--varial-gray-500, #6B6763);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
}

@media (max-width: 575.98px) {
  .results-control-cluster {
    align-items: stretch;
    justify-content: flex-start;
    width: 100%;
  }

  .results-control-group:not(.results-control-group--global) {
    flex: 1 1 100%;
    justify-content: space-between;
  }
}

/* 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);
}

/* 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;
}

/* Co-location benefit bridge: a five-row table mixing GWh volumes with $M earnings, where the
   bottom line can be negative. Fixed column widths stop the explanation column from squeezing
   the figures, and tabular numerals line the figures up on the decimal point so the bridge
   reads as an arithmetic chain rather than five unrelated numbers. */
.var-bridge-table .var-bridge-measure {
  width: 22rem;
}

.var-bridge-table .var-bridge-value {
  width: 9rem;
}

.var-bridge-table .var-bridge-figure {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* The uplift is the answer the bridge is built to give, so it reads as the total it is. */
.var-bridge-table .var-bridge-total > * {
  border-top: 2px solid var(--bs-border-color, #dee2e6);
}

.var-bridge-table .var-bridge-total th,
.var-bridge-table .var-bridge-total .var-bridge-figure {
  font-weight: 600;
}
