/* ==========================================================================
   Dalphene Index — charts.css
   Styles for the shared chart library (lib/charts.py) + hover layer
   (assets/charts.js). Extends app.css — same tokens, same hairlines.

   VALIDATED CATEGORICAL PALETTE (dark surface #0a0a0e), fixed slot order —
   passed all 6 checks of scripts/validate_palette.js. Never reordered,
   never cycled, color follows the entity:
     s1 #8f7aff purple  = Lasers & Light
     s2 #d465bd pink    = Injectables
     s3 #bd8a2f gold    = Body Contouring
     s4 #22a186 teal    = Skin & Topicals
     s5 #5f8dff blue    = RF & Microneedling
     s7 #3a3a44 neutral = Others / overflow
   Scoped under .viz so the rest of the site keeps its app.css values.
   Light-theme variants are darkened same-hue steps for the white surface.
   ========================================================================== */

.viz .s1 { --series: #8f7aff; }
.viz .s2 { --series: #d465bd; }
.viz .s3 { --series: #bd8a2f; }
.viz .s4 { --series: #22a186; }
.viz .s5 { --series: #5f8dff; }
.viz .s6 { --series: #c884bd; }
.viz .s7 { --series: #3a3a44; }

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .viz .s1 { --series: #6b50e6; }
  :root:not([data-theme="dark"]) .viz .s2 { --series: #b8449b; }
  :root:not([data-theme="dark"]) .viz .s3 { --series: #8f6512; }
  :root:not([data-theme="dark"]) .viz .s4 { --series: #0e8569; }
  :root:not([data-theme="dark"]) .viz .s5 { --series: #2c63e0; }
  :root:not([data-theme="dark"]) .viz .s6 { --series: #8d5384; }
  :root:not([data-theme="dark"]) .viz .s7 { --series: #b9b9c2; }
}
:root[data-theme="dark"] .viz .s1 { --series: #8f7aff; }
:root[data-theme="dark"] .viz .s2 { --series: #d465bd; }
:root[data-theme="dark"] .viz .s3 { --series: #bd8a2f; }
:root[data-theme="dark"] .viz .s4 { --series: #22a186; }
:root[data-theme="dark"] .viz .s5 { --series: #5f8dff; }
:root[data-theme="dark"] .viz .s6 { --series: #c884bd; }
:root[data-theme="dark"] .viz .s7 { --series: #3a3a44; }
:root[data-theme="light"] .viz .s1 { --series: #6b50e6; }
:root[data-theme="light"] .viz .s2 { --series: #b8449b; }
:root[data-theme="light"] .viz .s3 { --series: #8f6512; }
:root[data-theme="light"] .viz .s4 { --series: #0e8569; }
:root[data-theme="light"] .viz .s5 { --series: #2c63e0; }
:root[data-theme="light"] .viz .s6 { --series: #8d5384; }
:root[data-theme="light"] .viz .s7 { --series: #b9b9c2; }

/* ==========================================================================
   figure frame
   ========================================================================== */

.fig {
  position: relative;
  margin: 0;
  padding: var(--sp-3, 12px);
  background: var(--surface, #101015);
  border: 1px solid var(--border, #24242c);
  border-radius: var(--r-lg, 8px);
  min-width: 0;
}
@media (min-width: 820px) { .fig { padding: var(--sp-4, 16px); } }

.fig-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin-bottom: 10px;
}
.fig-title { margin: 0; font-size: 13px; font-weight: 500; color: var(--text, #f2f2f5); }
.fig-unit { margin: 0; font-size: 12px; color: var(--text-dim, #7c7c88); text-align: right; }

/* hero readout — proportional figures, same sans as everything else */
.fig-hero { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.fig-hero-num {
  font-size: 40px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--text, #f2f2f5);
  font-variant-numeric: normal;   /* proportional at display size, per spec */
}
@media (min-width: 820px) { .fig-hero-num { font-size: 48px; } }
.fig-hero-cap { font-size: 13px; color: var(--text-muted, #a1a1ac); }

/* computed takeaway — one sentence, under the title, above the plot.
   Emphasised against the unit line but never a heading: same 12–13px
   product-UI scale, no serif, no callout box. Numbers step up into the
   text token so the finding can be scanned without reading every word. */
.fig-takeaway {
  margin: -2px 0 10px;
  max-width: 72ch;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-muted, #a1a1ac);
  overflow-wrap: break-word;   /* a long applicant name never widens the page */
  text-wrap: pretty;
}
.fig-takeaway .fig-tk-n { color: var(--text, #f2f2f5); font-weight: 600; }
@media (min-width: 820px) { .fig-takeaway { font-size: 13px; } }

/* body: chart + (optionally) a side legend on wide screens */
.fig-body { min-width: 0; }
.fig--legend-side .fig-body { display: block; }
@media (min-width: 820px) {
  .fig--legend-side .fig-body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 218px;
    gap: 16px;
    align-items: start;
  }
}

.fig-scroll {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  min-width: 0;
}
.fig-canvas { max-width: 880px; }
.fig-svg { display: block; width: 100%; height: auto; }
.fig-svg text {
  font-family: var(--font-sans, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif);
  font-size: 11px;
  fill: var(--text-dim, #7c7c88);
}
.fig-svg .num, .fig-tick { font-variant-numeric: tabular-nums; }

/* marks ------------------------------------------------------------------ */
.fig-grid { stroke: var(--hairline, rgba(255,255,255,.06)); stroke-width: 1; }
.fig-axis { stroke: var(--border, #24242c); stroke-width: 1; }

.fig-band { fill: var(--series, #8f7aff); fill-opacity: .85; transition: opacity .12s ease; }
.fig-bandgap { fill: none; stroke: var(--bg, #0a0a0e); stroke-width: 2; }
.fig-partial { fill: var(--surface, #101015); opacity: .55; pointer-events: none; }

.fig-line {
  fill: none;
  stroke: var(--series, #8f7aff);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
  transition: opacity .12s ease;
}
.fig-dot {
  fill: var(--series, #8f7aff);
  stroke: var(--surface, #101015);    /* the 2px surface ring */
  stroke-width: 2;
  transition: opacity .12s ease;
}
.fig-dot--partial { fill: var(--surface, #101015); stroke: var(--series, #8f7aff); }

.fig-seg { fill: var(--series, #8f7aff); transition: opacity .12s ease; }

/* text on marks: text tokens only; in-band labels pick ink for the fills */
.fig-svg .fig-inlabel { fill: #08080c; font-weight: 600; font-size: 11px; pointer-events: none; }
.fig-endlabel { fill: var(--text-muted, #a1a1ac); font-size: 11px; }
.fig-collabel { fill: var(--text-muted, #a1a1ac); font-size: 11px; }

/* hover layer ------------------------------------------------------------ */
.fig-cross { stroke: var(--border-2, #33333d); stroke-width: 1; pointer-events: none; }
.fig-cross[hidden] { display: none; }
.fig-hit:focus-visible, .fig-hitxy:focus-visible {
  outline: 2px solid var(--accent, #7c5cff);
}
.fig .is-dim { opacity: .22; }
.fig .is-hot { opacity: .85; }

.fig-tip {
  position: absolute;
  z-index: 40;
  max-width: min(260px, calc(100% - 16px));
  padding: 8px 10px;
  background: var(--surface, #101015);
  border: 1px solid var(--border, #24242c);
  border-radius: var(--r-lg, 8px);
  box-shadow: var(--sh-pop, 0 8px 24px rgba(0,0,0,.55));
  font-size: 12px;
  line-height: 1.45;
  color: var(--text-muted, #a1a1ac);
  pointer-events: none;
}
.fig-tip[hidden] { display: none; }
.fig-tip .ftt {
  display: block;
  margin-bottom: 4px;
  font-weight: 600;
  color: var(--text, #f2f2f5);
  font-variant-numeric: tabular-nums;
}
.fig-tip .ftr { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
/* values lead, labels follow; series keyed by a short line, not a box */
.fig-tip .ftr-v {
  min-width: 3.5ch;
  text-align: right;
  font-weight: 600;
  color: var(--text, #f2f2f5);
  font-variant-numeric: tabular-nums;
}
.fig-tip .tk {
  flex: 0 0 10px;
  width: 10px; height: 2px;
  border-radius: 1px;
  background: var(--series, #8f7aff);
}
.fig-tip .ftr-l {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fig-tip .ftr--total { margin-top: 3px; padding-top: 3px;
  border-top: 1px solid var(--hairline, rgba(255,255,255,.06)); }
.fig-tip .ftr--muted .ftr-v, .fig-tip .ftr--muted { color: var(--text-dim, #7c7c88); }

/* legend ----------------------------------------------------------------- */
.fig-legend {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 10px;
  min-width: 0;
}
@media (min-width: 820px) { .fig--legend-side .fig-legend { margin-top: 0; } }
.fig-lg-row {
  display: grid;
  /* swatch · label (shrinks first) · count · share — the two number columns
     hold their own width so they stay aligned down the list at any label
     length, including 375px where the legend sits under the chart */
  grid-template-columns: 14px minmax(0, 1fr) minmax(4ch, auto) minmax(4ch, auto);
  align-items: center;
  column-gap: 8px;
  padding: 5px 6px;
  border: 0;
  border-radius: var(--r-md, 6px);
  background: transparent;
  text-align: left;
  font-size: 12px;
  color: var(--text-muted, #a1a1ac);
  cursor: default;
  transition: background-color .12s ease;
}
button.fig-lg-row { cursor: pointer; }
.fig-lg-row:hover, .fig-lg-row:focus-visible { background: var(--surface-2, #17171d); }
.fig-swatch {
  width: 10px; height: 10px;
  justify-self: center;          /* the key column is 14px, sized for the
                                    shape marks; the plain square stays 10px */
  border-radius: 2px;
  background: var(--series, #8f7aff);
}
.fig-lg-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text, #f2f2f5);
}
.fig-lg-val {
  font-weight: 600;
  color: var(--text, #f2f2f5);
  text-align: right;
  font-variant-numeric: tabular-nums;   /* columns → tabular, per spec */
}
.fig-lg-share {
  color: var(--text-dim, #7c7c88);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
/* the collapsed row: neutral swatch, muted name, same number columns */
.fig-lg-row--other .fig-lg-label { color: var(--text-muted, #a1a1ac); }
.fig-lg-note { margin: 6px 6px 0; font-size: 11px; color: var(--text-dim, #7c7c88);
  line-height: 1.45; overflow-wrap: break-word; }
.fig-lg-note + .fig-lg-note { margin-top: 4px; }
.fig-foot { margin: 8px 0 0; font-size: 11px; color: var(--text-dim, #7c7c88); }

/* ==========================================================================
   horizontal bars (HTML marks)
   ========================================================================== */

.hbar-list { display: flex; flex-direction: column; }
.hbar {
  display: grid;
  grid-template-columns: minmax(0, 44%) minmax(0, 1fr) auto auto;
  align-items: center;
  column-gap: 10px;
  min-height: 36px;
  padding: 4px 6px;
  border-bottom: 1px solid var(--hairline, rgba(255,255,255,.06));
}
.hbar:last-child { border-bottom: 0; }
.hbar-id { min-width: 0; display: flex; flex-direction: column; }
.hbar-label {
  font-size: 13px;
  font-weight: 500;
  color: var(--text, #f2f2f5);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
a.hbar-label:hover { color: var(--accent-text, #a48cff); }
.hbar-sub { font-size: 11px; color: var(--text-dim, #7c7c88); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.hbar-track {
  position: relative;
  height: 6px;
  border-radius: 3px;
  background: var(--surface-2, #17171d);
  overflow: hidden;
  min-width: 40px;
}
.hbar-fill {
  position: absolute;
  inset: 0 auto 0 0;
  border-radius: 0 3px 3px 0;   /* rounded data-end, square at the baseline */
  background: var(--series, #8f7aff);
}
.hbar-val { font-size: 13px; font-weight: 600; color: var(--text, #f2f2f5);
  text-align: right; min-width: 3ch; }

/* ==========================================================================
   sparkline
   ========================================================================== */

.spark path { fill: none; stroke: var(--series, #8f7aff); stroke-width: 1.5;
  stroke-linejoin: round; stroke-linecap: round; }
.spark circle { fill: var(--series, #8f7aff); stroke: var(--surface, #101015);
  stroke-width: 1.5; }

/* ==========================================================================
   delta chips — STATUS tokens, arrow glyph so sign is never color-alone
   ========================================================================== */

.chip-delta {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  height: 20px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--surface-2, #17171d);
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  color: var(--text-dim, #7c7c88);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.chip-delta .chip-arrow { font-size: 11px; }
.chip-delta.up { color: var(--positive-text, #3fb39d); }
.chip-delta.down { color: var(--danger-text, #e0655a); }
.chip-delta.flat { color: var(--text-dim, #7c7c88); }
.chip-delta--na { cursor: help; }

/* ==========================================================================
   initial tiles — no logos, ever
   ========================================================================== */

.lb-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  border-radius: 8px;
  border-left: 3px solid var(--series, #8f7aff);
  background: var(--series-weak, rgba(143,122,255,.12));
  color: var(--text, #f2f2f5);           /* initials in the text token */
  font-weight: 600;
  letter-spacing: .02em;
}
@supports (background: color-mix(in srgb, red 16%, transparent)) {
  .lb-tile { background: color-mix(in srgb, var(--series, #8f7aff) 16%, transparent); }
}
.lb-tile--md { width: 32px; height: 32px; font-size: 12px; }
.lb-tile--sm { width: 24px; height: 24px; font-size: 10px; border-left-width: 2px;
  border-radius: 6px; }

/* ==========================================================================
   tabs + segmented controls (standard UI, above the chart card)
   ========================================================================== */

/* A tab strip is content-width, so on a phone it can be wider than the column
   it sits in. As a flex ITEM its automatic minimum size refuses to shrink, so
   `max-width: 100%` alone does not hold it — it pushed 11px past the viewport
   inside .lb-sort on /rankings/devices, where html's overflow-x:clip silently
   ate the edge of the last control. min-width:0 lets it shrink and the strip
   scrolls its own tabs instead of clipping them. */
.fig-tabs { display: flex; gap: 2px; padding: 2px; margin-bottom: 8px;
  background: var(--surface-2, #17171d); border: 1px solid var(--border, #24242c);
  border-radius: var(--r-md, 6px); width: fit-content; max-width: 100%;
  min-width: 0; overflow-x: auto; overscroll-behavior-x: contain; }
.fig-tabs button {
  height: 30px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--r-sm, 4px);
  background: transparent;
  color: var(--text-muted, #a1a1ac);
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color .12s ease, color .12s ease;
}
.fig-tabs button[aria-selected="true"] {
  background: var(--surface, #101015);
  color: var(--text, #f2f2f5);
  box-shadow: 0 0 0 1px var(--border-2, #33333d);
}
.fig-pane[hidden] { display: none; }

@media (prefers-reduced-motion: reduce) {
  .fig *, .chip-delta, .hbar-fill { transition: none !important; }
}
@media print {
  .fig-tip { display: none !important; }
}

/* ==========================================================================
   ORDINAL RAMP — r1 … r4
   Validated with the dataviz skill's validate_palette.js --ordinal in BOTH
   modes: lightness monotone, adjacent delta-L >= 0.06, single hue, and the
   step nearest the surface still clearing the 2:1 contrast floor. The first
   attempt FAILED that last check on the dark surface (#322c5e read at
   1.37:1), so the whole ramp was re-stepped rather than eyeballed. On the
   light surface the ramp runs the other way — strongest is darkest — which
   is why the two theme blocks are not mirror images of one another.
   ONE hue, strong → weak, for segments that are steps of an ORDERED scale
   (started recently → started earlier → start date unknown; publication
   types by study design). This is the sanctioned sequential case, NOT a
   value-ramp laid over nominal categories: it is never used to colour
   entities, and it never mixes with the s1–s5 category slots inside a mark.
   The neutral s7 always carries the "unknown" class, so a missing value is
   drawn as its own thing and never folded into a neighbouring step.
   ========================================================================== */

.viz .r1 { --series: #c7bcff; }
.viz .r2 { --series: #a08fef; }
.viz .r3 { --series: #7b68d4; }
.viz .r4 { --series: #5a4aa8; }

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .viz .r1 { --series: #3f2b96; }
  :root:not([data-theme="dark"]) .viz .r2 { --series: #5f47c4; }
  :root:not([data-theme="dark"]) .viz .r3 { --series: #8069dd; }
  :root:not([data-theme="dark"]) .viz .r4 { --series: #a190e8; }
}
:root[data-theme="dark"] .viz .r1 { --series: #c7bcff; }
:root[data-theme="dark"] .viz .r2 { --series: #a08fef; }
:root[data-theme="dark"] .viz .r3 { --series: #7b68d4; }
:root[data-theme="dark"] .viz .r4 { --series: #5a4aa8; }
:root[data-theme="light"] .viz .r1 { --series: #3f2b96; }
:root[data-theme="light"] .viz .r2 { --series: #5f47c4; }
:root[data-theme="light"] .viz .r3 { --series: #8069dd; }
:root[data-theme="light"] .viz .r4 { --series: #a190e8; }

/* ==========================================================================
   ROW FORMS — dot_range, lollipop, stacked_rows, dot_strip, dumbbell
   One entity per row, one shared value axis. Marks stay thin; the numbers
   live in real text on the label line, so nothing is gated behind hover and
   no label can be clipped by the mark it belongs to.
   ========================================================================== */

/* the entity's name, and the muted meta string carrying its exact values */
.fig--rows .fig-rowlabel { fill: var(--text, #f2f2f5); font-size: 12px; }
.fig--rows .fig-rowmeta { fill: var(--text-dim, #7c7c88); font-size: 11px; }
/* a thin-denominator row keeps a READABLE label — the printed count is the
   redundant channel that stops opacity being the only signal */
.fig--rows .fig-rowlabel.is-thin { fill: var(--text-muted, #a1a1ac); }
.fig--rows .fig-empty { fill: var(--text-dim, #7c7c88); font-size: 11px; }

/* interquartile range bar: a wash of the entity's own hue, round-capped so
   the interval reads as an interval and not as a bar grown from zero */
.fig-range {
  stroke: var(--series, #8f7aff);
  stroke-width: 7;
  stroke-linecap: round;
  stroke-opacity: .38;
  transition: stroke-opacity .12s ease;
}
/* the median / value dot — ≥8px, with the 2px surface ring that keeps it
   legible where it overlaps its own range bar */
.fig-mid {
  fill: var(--series, #8f7aff);
  stroke: var(--surface, #101015);
  stroke-width: 2;
  transition: opacity .12s ease;
}
/* the earlier end of a dumbbell: hollow, so direction is never colour-alone */
.fig-mid--from { fill: var(--surface, #101015); stroke: var(--series, #8f7aff); stroke-width: 2.5; }

.fig-stem {
  stroke: var(--series, #8f7aff);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-opacity: .5;
  transition: stroke-opacity .12s ease;
}
.fig-conn { stroke: var(--border-2, #33333d); stroke-width: 2; stroke-linecap: round; }

/* dot-strip / scatter points — shape is the second identity channel */
.fig-pt {
  fill: var(--series, #8f7aff);
  stroke: var(--surface, #101015);
  stroke-width: 2;
  transition: opacity .12s ease;
}

/* a single neutral reference rule, no shading either side: neither side of
   it is good or bad, and a band would say otherwise */
.fig-ref { stroke: var(--border-2, #33333d); stroke-width: 1; }
.fig-reflabel { fill: var(--text-dim, #7c7c88); font-size: 10.5px; }

.fig-ptlabel { fill: var(--text-muted, #a1a1ac); font-size: 11px; }
.fig-axtitle { fill: var(--text-dim, #7c7c88); font-size: 11px; }

/* rows computed from very few records: reduced opacity is the SECOND cue,
   never the only one — the count is printed on the row and the threshold is
   named in the figure's own note */
.fig--rows .fig-range.is-thin { stroke-opacity: .18; }
.fig--rows .fig-stem.is-thin { stroke-opacity: .24; }
.fig--rows .fig-mid.is-thin, .fig--rows .fig-conn.is-thin { opacity: .5; }

/* hover/focus lift on the row the pointer is in */
.fig--rows .fig-range.is-hot { stroke-opacity: .6; }
.fig--rows .fig-stem.is-hot { stroke-opacity: .8; }
.fig--rows .fig-mid.is-hot, .fig--rows .fig-seg.is-hot,
.fig--rows .fig-pt.is-hot, .fig--scatter .fig-pt.is-hot { opacity: 1; filter: brightness(1.18); }
.fig-hit:focus-visible { outline: 2px solid var(--accent, #7c5cff); outline-offset: 1px; }

/* in-segment label: ink chosen by the FILL's luminance, which flips with the
   theme because the ordinal ramp's strong step is light on the dark surface
   and dark on the light one */
.fig--stackrows .fig-inlabel { fill: #08080c; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .fig--stackrows .fig-inlabel { fill: #ffffff; }
}
:root[data-theme="dark"] .fig--stackrows .fig-inlabel { fill: #08080c; }
:root[data-theme="light"] .fig--stackrows .fig-inlabel { fill: #ffffff; }

/* visible scroll affordance — on EVERY scrolling figure, not just the row
   forms: any figure whose canvas is wider than the phone hands the reader a
   sideways scroll, and a scroll with no visible edge is a scroll nobody
   finds. The cover layers scroll WITH the content (local), the shadows do
   not (scroll), so an inner shadow appears at exactly the edge that still
   has content beyond it, and only then. */
.fig-scroll {
  background:
    linear-gradient(to right, var(--surface, #101015) 40%, rgba(0, 0, 0, 0))
      left / 24px 100% no-repeat local,
    linear-gradient(to left, var(--surface, #101015) 40%, rgba(0, 0, 0, 0))
      right / 24px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, rgba(0, 0, 0, .30), rgba(0, 0, 0, 0))
      left / 11px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, .30), rgba(0, 0, 0, 0))
      right / 11px 100% no-repeat scroll;
}

@media (prefers-reduced-motion: reduce) {
  .fig-range, .fig-stem, .fig-mid, .fig-pt { transition: none !important; }
}

/* legend key that mirrors a shape-encoded mark (the dot strip). The ring is
   the same 2px surface ring the mark on the chart carries, so the key and the
   chart read as the same object. */
.fig-swatch-mark { flex: none; display: block; overflow: visible;
  width: 14px; height: 14px; }
.fig-swatch-mark .fig-pt { fill: var(--series, #8f7aff); stroke: none; }
.fig-swatch-mark .fig-pt--hollow {
  fill: var(--surface, #101015);
  stroke: var(--series, #8f7aff);
  stroke-width: 2.5;
}
