/* ==========================================================================
   Chart layer. Palette validated with the dataviz validator (all 5 checks PASS
   on the light surface): lightness band, chroma floor, CVD separation,
   normal-vision floor, contrast.

     #6E9B3C  green   series / magnitude
     #1183A0  teal    diverging positive
     #C4761B  amber   diverging negative

   A green/red diverging pair was rejected: deutan separation measured ΔE 3.0,
   i.e. invisible to deuteranopes. Teal/amber measures 17.6.
   ========================================================================== */

:root {
  --c-series: #6E9B3C;
  --c-pos:    #1183A0;
  --c-neg:    #C4761B;
  --c-grid:   rgba(0,0,0,.10);
  --c-ref:    rgba(0,0,0,.34);
  --c-ink:    #1C1C1C;
  --c-muted:  rgba(0,0,0,.62);
}

.figure {
  background: var(--surface);
  border: 1px solid var(--hairline-soft);
  border-radius: var(--r-card, 24px);
  padding: var(--s-5);
  box-shadow: var(--e-1);
}
.figure > figcaption { margin: 0 0 var(--s-4); }
.figure .fig-title { font-weight: 600; font-size: var(--t-lg); color: var(--c-ink); margin: 0 0 var(--s-1); letter-spacing: -.01em; }
.figure .fig-sub   { font-size: var(--t-sm); color: var(--c-muted); margin: 0; }
.figure svg { width: 100%; height: auto; display: block; overflow: visible; }
.figure .fig-source { font-size: var(--t-xs); color: var(--c-muted); margin: var(--s-4) 0 0;
                      padding-top: var(--s-3); border-top: 1px solid var(--hairline-soft); }

/* legend: present whenever 2+ things are encoded */
.fig-legend { display: flex; flex-wrap: wrap; gap: var(--s-4); margin: 0 0 var(--s-3); padding: 0; list-style: none; }
.fig-legend li { display: flex; align-items: center; gap: var(--s-2); font-size: var(--t-sm); color: var(--c-muted); }
.fig-legend .swatch { width: 18px; height: 3px; border-radius: 2px; flex: none; }
.fig-legend .swatch.dash { background: none; border-top: 2px dashed var(--c-ref); height: 0; }

/* text always wears text tokens, never the series colour */
.figure text { font-family: var(--f-body); }
.ax-label  { font-size: 12px; fill: var(--c-muted); }
.val-label { font-size: 13px; font-weight: 600; fill: var(--c-ink); }
.mark-label{ font-size: 12px; font-weight: 600; fill: var(--c-ink); }

/* stat tiles, for the numbers that are not a chart */
.stat-row { display: grid; grid-template-columns: repeat(auto-fit,minmax(170px,1fr)); gap: var(--s-4); }
.stat-tile { background: var(--surface); border: 1px solid var(--hairline-soft); border-radius: var(--r-card,24px);
             padding: var(--s-5); text-align: center; box-shadow: var(--e-1); }
.stat-tile .n { font-size: 40px; font-weight: 600; letter-spacing: -.02em; line-height: 1; color: var(--c-series); }
.stat-tile .n.alt { color: var(--c-pos); }
.stat-tile p { font-size: var(--t-sm); color: var(--c-muted); margin: var(--s-3) 0 0; }

/* data table fallback, always present so identity is never colour-alone */
.fig-table { width: 100%; border-collapse: collapse; font-size: var(--t-sm); margin-top: var(--s-4); }
.fig-table th, .fig-table td { text-align: left; padding: var(--s-2) var(--s-3); border-bottom: 1px solid var(--hairline-soft); }
.fig-table th { font-weight: 600; color: var(--c-muted); font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .08em; }
details.fig-data > summary { cursor: pointer; font-size: var(--t-xs); color: var(--c-muted); padding: var(--s-2) 0;
                             list-style: none; text-decoration: underline; }
details.fig-data > summary::-webkit-details-marker { display: none; }

@media (prefers-contrast: more) {
  .figure { border: 2px solid var(--c-ink); }
}
@media (forced-colors: active) {
  .figure svg path, .figure svg rect, .figure svg line { forced-color-adjust: none; }
}

/* ==========================================================================
   Scroll-draw animation. Charts are marked data-chart; wb-motion.js observes
   them and adds .in when they enter the viewport. Bars grow from the baseline,
   lines draw left to right, value labels fade in last. All of it resolves
   instantly under prefers-reduced-motion or if the observer never fires.
   ========================================================================== */
.js-motion [data-chart] .bar {
  transform-box: fill-box;      /* SVG: scale from the rect's own box, not the canvas origin */
  transform: scaleX(0); transform-origin: 0 50%;
  transition: transform .9s cubic-bezier(.72,0,.45,1);
  transition-delay: var(--d, 0s);
}
.js-motion [data-chart].in .bar { transform: scaleX(1); }
.js-motion [data-chart] .bar.neg { transform-origin: 100% 50%; }

.js-motion [data-chart] .val-label,
.js-motion [data-chart] .mark-label,
.js-motion [data-chart] .mark-dot {
  opacity: 0; transition: opacity .5s ease .85s;
}
.js-motion [data-chart].in .val-label,
.js-motion [data-chart].in .mark-label,
.js-motion [data-chart].in .mark-dot { opacity: 1; }

/* line series: dasharray/offset are set from getTotalLength() in wb-motion.js */
.js-motion [data-chart] .series { transition: stroke-dashoffset 2.2s cubic-bezier(.72,0,.45,1) .15s; }
.js-motion [data-chart].in .series { stroke-dashoffset: 0 !important; }

@media (prefers-reduced-motion: reduce) {
  [data-chart] .bar, [data-chart] .series,
  [data-chart] .val-label, [data-chart] .mark-label, [data-chart] .mark-dot {
    transform: none !important; opacity: 1 !important;
    transition: none !important; stroke-dashoffset: 0 !important;
  }
}
