/*
 * ClearHorizon — chart tokens & primitives
 * Drop in AFTER wwwroot/css/clearhorizon-tokens.css, BEFORE app.css.
 * Everything here is additive: it introduces --chart-* tokens and replaces the
 * .ch-chart* / .ch-fan* / .ch-area* rules currently living in app.css (lines ~806-819,
 * ~1337-1344, ~1375-1384). Nothing in clearhorizon-tokens.css changes.
 *
 * Series colors are NOT new brand colors. c1..c6 are the hexes already in your
 * codebase (--ch-primary, --ch-accent, --ch-bucket-taxable, --ch-bucket-hsa) promoted
 * into an ordered categorical ramp, plus two additions (indigo, slate) chosen to sit
 * at the same lightness so no series visually outranks another.
 */

:root {
  /* ---- Categorical series ramp (use in order; never skip) ---- */
  --chart-c1: #1466B8;  /* azure  — tracks --ch-primary. Portfolio / base case / primary series */
  --chart-c2: #0E8A6E;  /* teal   — tracks --ch-accent.  Second comparison, Roth conversion, income */
  --chart-c3: #5B4FC7;  /* indigo — NEW. Third comparison line */
  --chart-c4: #8A5A0B;  /* ochre  — tracks --ch-bucket-taxable / --ch-warning */
  --chart-c5: #6B2C86;  /* plum   — tracks --ch-bucket-hsa */
  --chart-c6: #4A6274;  /* slate  — NEW. Cash, "inert" money, 6th series */

  /* ---- Semantic (meaning, never decoration) ---- */
  --chart-shortfall:      #A33D2D;                  /* tracks --ch-danger. Depletion, unmet spending */
  --chart-shortfall-wash: rgba(163, 61, 45, 0.10);
  --chart-caution:        #8A5A0B;                  /* tracks --ch-warning. Guardrail hit, RMD forced */
  --chart-positive:       #176B45;                  /* tracks --ch-success */

  /* ---- Plot chrome ---- */
  --chart-grid:         #E8EDF3;  /* deliberately lighter than --ch-border so grid sits BEHIND the card frame */
  --chart-baseline:     #D3DBE6;  /* the zero line and the x axis only */
  --chart-axis-text:    #5A6675;  /* = --ch-text-muted, 5.9:1 on white */
  --chart-label:        #0F1B26;  /* = --ch-text */
  --chart-crosshair:    #B4C0CD;
  --chart-annotation:   #8696A4;  /* = --ch-text-decorative. Retirement marker, era dividers */
  --chart-plot-hover:   rgba(20, 102, 184, 0.05);

  /* ---- Area & band fills ---- */
  /* Stronger than the handoff's 0.22/0.01: a translucent blue over WHITE washes out far faster than
     the same alpha over the dark surface, so matching the numbers made light mode read as nothing. */
  --chart-area-from:    rgba(20, 102, 184, 0.34);
  --chart-area-to:      rgba(20, 102, 184, 0.03);
  --chart-band-outer:   0.10;   /* p10-p90 fill-opacity */
  --chart-band-inner:   0.22;   /* p25-p75 fill-opacity */

  /* ---- Tooltip ---- */
  --chart-tip-bg:     #FFFFFF;
  --chart-tip-border: #D3DBE6;
  --chart-tip-shadow: 0 12px 32px -10px rgba(15, 27, 38, 0.28), 0 2px 6px rgba(15, 27, 38, 0.06);

  /* ---- Three-bucket strategy: its own scale, NOT the tax-bucket tokens ---- */
  --chart-bucket-cash:   #4A6274;  /* defensive money reads inert */
  --chart-bucket-income: #0E8A6E;
  --chart-bucket-growth: #1466B8;  /* the engine of the plan reads primary */

  /* ---- Geometry ---- */
  --chart-stroke:        2.25px;
  --chart-stroke-strong: 3px;
  --chart-hairline:      1px;
  --chart-dot:           3.5px;
  --chart-dot-hover:     5.5px;
  --chart-bar-radius:    3px;
  --chart-bar-fill:      0.64;   /* fraction of the slot a bar group occupies */
  --chart-pad-l:         64px;
  --chart-pad-r:         16px;
  --chart-pad-t:         12px;
  --chart-pad-b:         32px;
  --chart-y-ticks:       4;
}

@media (max-width: 620px) {
  :root { --chart-pad-l: 46px; --chart-pad-r: 10px; --chart-pad-b: 28px; }
}

[data-theme="dark"] {
  --chart-c1: #4FA3E8;
  --chart-c2: #3FC0A0;
  --chart-c3: #9A90EE;
  --chart-c4: #D8A23D;
  --chart-c5: #C58BD8;
  --chart-c6: #93A9BA;

  --chart-shortfall:      #E0685C;
  --chart-shortfall-wash: rgba(224, 104, 92, 0.16);
  --chart-caution:        #D8A23D;
  --chart-positive:       #34B27B;

  --chart-grid:         #1B2A38;
  --chart-baseline:     #2E4356;
  --chart-axis-text:    #9DB0BE;  /* 6.1:1 on --ch-surface */
  --chart-label:        #E7EEF4;
  --chart-crosshair:    #3A4E60;
  --chart-annotation:   #6B7E8D;
  --chart-plot-hover:   rgba(79, 163, 232, 0.09);

  --chart-area-from:    rgba(79, 163, 232, 0.30);
  --chart-area-to:      rgba(79, 163, 232, 0.02);
  --chart-band-outer:   0.14;
  --chart-band-inner:   0.28;

  --chart-tip-bg:     #1A2E40;
  --chart-tip-border: #2E4356;
  --chart-tip-shadow: 0 16px 40px -12px rgba(0, 0, 0, 0.7);

  --chart-bucket-cash:   #93A9BA;
  --chart-bucket-income: #3FC0A0;
  --chart-bucket-growth: #4FA3E8;
}

/* ============================================================================
   Chart frame
   The SVG is now sized in REAL pixels (width/height set from a measured
   container), not a fixed 800x320 viewBox. This is the one structural change:
   with a viewBox + preserveAspectRatio, an 11px axis label renders at ~7px in a
   520px-wide card and ~14px in a 1000px one. Real-pixel sizing keeps every label
   at its specified size at every breakpoint, which is what the AA commitment in
   §10 of the feature catalog actually requires.
   ============================================================================ */

.ch-chart { margin: 0; }
.ch-chart-svg { display: block; width: 100%; }
.ch-chart-plot { position: relative; }

/* Gridlines --------------------------------------------------------------- */
.ch-chart .ch-grid,
.ch-chart-svg .ch-grid {
  stroke: var(--chart-grid);
  stroke-width: var(--chart-hairline);
  shape-rendering: crispEdges;
}
.ch-chart-svg .ch-baseline {
  stroke: var(--chart-baseline);
  stroke-width: var(--chart-hairline);
  shape-rendering: crispEdges;
}

/* Axes -------------------------------------------------------------------- */
.ch-chart .ch-axis-y,
.ch-chart-svg .ch-axis-y {
  fill: var(--chart-axis-text);
  font: 500 12px/1 var(--ch-font-sans);
  text-anchor: end;
  font-variant-numeric: tabular-nums;
}
.ch-chart .ch-axis-x,
.ch-chart-svg .ch-axis-x {
  fill: var(--chart-axis-text);
  font: 500 12px/1 var(--ch-font-sans);
  text-anchor: middle;
  font-variant-numeric: tabular-nums;
}
.ch-chart-svg .ch-axis-title {
  fill: var(--chart-axis-text);
  font: 600 12px/1 var(--ch-font-sans);
  letter-spacing: 0.01em;
}

/* Series ------------------------------------------------------------------ */
.ch-chart-svg .ch-series {
  fill: none;
  stroke-width: var(--chart-stroke);
  stroke-linejoin: round;
  stroke-linecap: round;
}
.ch-chart-svg .ch-series-strong { stroke-width: var(--chart-stroke-strong); }

/* Line-style ladder. Series are distinguished by dash AND color (§10), so the
   ChartSeries `Dashed` bool becomes an index: 0..5. */
.ch-dash-0 { stroke-dasharray: none; }
.ch-dash-1 { stroke-dasharray: 7 5; }
.ch-dash-2 { stroke-dasharray: 2 4; }
.ch-dash-3 { stroke-dasharray: 11 4 2.5 4; }
.ch-dash-4 { stroke-dasharray: 1 4; }
.ch-dash-5 { stroke-dasharray: 6 3 1 3; }

/* Annotations ------------------------------------------------------------- */
.ch-chart .ch-retire-line,
.ch-chart-svg .ch-retire-line {
  stroke: var(--chart-annotation);
  stroke-width: 1.5;
  stroke-dasharray: 3 4;
}
.ch-chart .ch-retire-label,
.ch-chart-svg .ch-retire-label {
  fill: var(--chart-axis-text);
  font: 600 12px/1 var(--ch-font-sans);
}
.ch-chart-svg .ch-shortfall-line {
  stroke: var(--chart-shortfall);
  stroke-width: 1.5;
  stroke-dasharray: 4 3;
}
.ch-chart-svg .ch-shortfall-wash { fill: var(--chart-shortfall-wash); }

/* Monte Carlo fan --------------------------------------------------------- */
.ch-fan-outer  { fill: var(--chart-c1); fill-opacity: var(--chart-band-outer); }
.ch-fan-inner  { fill: var(--chart-c1); fill-opacity: var(--chart-band-inner); }
.ch-fan-median { stroke: var(--chart-c1); fill: none; stroke-width: var(--chart-stroke-strong); }
.ch-path-rough   { stroke: var(--chart-shortfall); fill: none; stroke-width: 1.5; opacity: 0.75; }
.ch-path-typical { stroke: var(--chart-annotation); fill: none; stroke-width: 1.5; opacity: 0.75; }
.ch-path-lucky   { stroke: var(--chart-positive);  fill: none; stroke-width: 1.5; opacity: 0.75; }

/* Three-bucket stacked area ---------------------------------------------- */
.ch-area-cash   { fill: var(--chart-bucket-cash); }
.ch-area-income { fill: var(--chart-bucket-income); }
.ch-area-growth { fill: var(--chart-bucket-growth); }

/* Bars ------------------------------------------------------------------- */
.ch-chart-svg .ch-bar { transition: opacity var(--ch-motion-micro) var(--ch-ease); }
.ch-chart-svg .ch-bar-dim { opacity: 0.4; }

/* Legend ----------------------------------------------------------------- */
.ch-chart-legend {
  display: flex;
  flex-wrap: wrap;                   /* was nowrap — 5 Compare series overflowed on mobile */
  gap: var(--ch-sp-2) var(--ch-sp-4);
  margin-top: var(--ch-sp-3);
  font-size: var(--ch-fs-13);
  color: var(--chart-axis-text);
}
.ch-chart-key { display: inline-flex; align-items: center; gap: 8px; }
.ch-chart-key-btn {
  background: none; border: 0; padding: 6px 8px; margin: -6px -8px;
  border-radius: var(--ch-radius-sm);
  min-height: 32px; cursor: pointer;
  font: 500 var(--ch-fs-13)/1 var(--ch-font-sans);
  color: var(--chart-label);
  transition: background-color var(--ch-motion-micro) var(--ch-ease);
}
.ch-chart-key-btn:hover { background: var(--chart-plot-hover); }
.ch-chart-key-btn:focus-visible { outline: 2px solid var(--ch-primary); outline-offset: 2px; }
.ch-chart-key-btn[aria-pressed="false"] { opacity: 0.45; }

/* Tooltip ---------------------------------------------------------------- */
.ch-chart-tip {
  position: absolute; top: 10px; z-index: 5;
  pointer-events: none;
  min-width: 188px;
  padding: 10px 12px;
  display: flex; flex-direction: column; gap: 7px;
  background: var(--chart-tip-bg);
  border: 1px solid var(--chart-tip-border);
  border-radius: var(--ch-radius-md);
  box-shadow: var(--chart-tip-shadow);
}
.ch-chart-tip-head { font: 600 var(--ch-fs-12)/1.3 var(--ch-font-sans); color: var(--chart-label); }
.ch-chart-tip-rule { height: 1px; background: var(--chart-tip-border); }
.ch-chart-tip-row  { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.ch-chart-tip-name { display: flex; align-items: center; gap: 7px; font: 400 var(--ch-fs-13)/1.4 var(--ch-font-sans); color: var(--chart-axis-text); white-space: nowrap; }
.ch-chart-tip-dot  { width: 9px; height: 9px; border-radius: 2px; flex: none; }
.ch-chart-tip-val  { font: 600 var(--ch-fs-13)/1.4 var(--ch-font-sans); color: var(--chart-label); font-variant-numeric: tabular-nums; }
.ch-chart-tip-note { font: 400 var(--ch-fs-12)/1.35 var(--ch-font-sans); color: var(--chart-axis-text); }

/* Data-table fallback ---------------------------------------------------- */
.ch-chart-data { margin-top: var(--ch-sp-4); }
.ch-chart-data summary {
  cursor: pointer;
  color: var(--ch-primary-text);
  font: var(--ch-fw-semibold) var(--ch-fs-13)/1 var(--ch-font-sans);
  padding: 6px 0;
  min-height: 32px;
  display: flex; align-items: center;
}
.ch-chart-data summary:focus-visible { outline: 2px solid var(--ch-primary); outline-offset: 2px; border-radius: var(--ch-radius-sm); }
.ch-chart-data table { margin-top: var(--ch-sp-3); }

/* Load / change animation ------------------------------------------------
   One reveal per chart: a clip rect wipes left-to-right. Because it animates a
   clip and not stroke-dasharray, dashed series keep their dash pattern. */
.ch-chart-reveal rect { transition: width 800ms var(--ch-ease); }

@media (prefers-reduced-motion: reduce) {
  .ch-chart-reveal rect { transition: none; }
}
