:root {
  /* ---- Brand ---- */
  --tbl-navy: #101F5B;
  --tbl-blue: #0072B2;
  --tbl-sky:  #63AAFF;

  /* ---- Categorical series (apply in order) ---- */
  --tbl-cat1: #0072B2;  /* blue   */
  --tbl-cat2: #E69F00;  /* amber  (alias: yellow)  */
  --tbl-cat3: #8856BF;  /* violet (alias: purple)  */
  --tbl-cat4: #2A8B3A;  /* green  */
  --tbl-cat5: #B8302C;  /* red    */
  --tbl-cat6: #CC79A7;  /* rose   (alias: pink)    */
  --tbl-cat7: #7A5230;  /* russet (alias: brown)   */

  /* ---- Tonal scales (50 lightest → 700 darkest, 8 tiers at fixed L*) ---- */
  --tbl-blue-50:  #95DAFF;  --tbl-blue-100: #77BEFF;  --tbl-blue-200: #58A3E7;  --tbl-blue-300: #3689CB;
  --tbl-blue-400: #0070AF;  --tbl-blue-500: #005794;  --tbl-blue-600: #00407A;  --tbl-blue-700: #002B61;

  --tbl-amber-50:  #FFC63D;  --tbl-amber-100: #F4AB1A;  --tbl-amber-200: #D59000;  --tbl-amber-300: #B67700;
  --tbl-amber-400: #985E00;  --tbl-amber-500: #7B4600;  --tbl-amber-600: #612F00;  --tbl-amber-700: #4B1900;

  --tbl-violet-50:  #F6BCFF;  --tbl-violet-100: #D8A0FF;  --tbl-violet-200: #BC85F4;  --tbl-violet-300: #9F6BD7;
  --tbl-violet-400: #8452BB;  --tbl-violet-500: #693A9F;  --tbl-violet-600: #4E2185;  --tbl-violet-700: #33076B;

  --tbl-green-50:  #8CE990;  --tbl-green-100: #70CD76;  --tbl-green-200: #54B15C;  --tbl-green-300: #379644;
  --tbl-green-400: #127B2C;  --tbl-green-500: #006213;  --tbl-green-600: #004900;  --tbl-green-700: #003100;

  --tbl-red-50:  #FFA895;  --tbl-red-100: #FF8C7B;  --tbl-red-200: #FF7062;  --tbl-red-300: #E1554A;
  --tbl-red-400: #C13933;  --tbl-red-500: #A2191D;  --tbl-red-600: #840006;  --tbl-red-700: #670000;

  --tbl-rose-50:  #FFBAE9;  --tbl-rose-100: #F49ECD;  --tbl-rose-200: #D783B2;  --tbl-rose-300: #BB6997;
  --tbl-rose-400: #9F507D;  --tbl-rose-500: #843764;  --tbl-rose-600: #691D4C;  --tbl-rose-700: #4F0035;

  --tbl-russet-50:  #FDCAA3;  --tbl-russet-100: #E0AF89;  --tbl-russet-200: #C3946F;  --tbl-russet-300: #A77A56;
  --tbl-russet-400: #8B623F;  --tbl-russet-500: #714A28;  --tbl-russet-600: #563313;  --tbl-russet-700: #3E1E00;

  /* ---- Structural (non-data) ---- */
  --tbl-bg:           #FFFFFF;
  --tbl-bg-subtle:    #F6F7F9;
  --tbl-bg-highlight: #D9EAFF;
  --tbl-border:       #E5E5E5;
  --tbl-gridline:     #F0F0F0;
  --tbl-axis-stroke:  #999999;

  /* ---- Text ---- */
  --tbl-text-heading: #1A1A2E;
  --tbl-text-body:    #4A4A4A;
  --tbl-text-muted:   #6D6D6D;
  --tbl-text-axis:    #666666;

  /* ---- Annotations ---- */
  --tbl-annotation-dim: #BBBBBB;

  /* ---- Chart marks ---- */
  --tbl-mark-black: #000000;  /* baseline/total/threshold lines — strong, neutral */
}

/* =========================================================================
 * Typography â€” Figtree weight scale and font variables.
 * ========================================================================= */
:root {
  --tbl-font-sans: 'Figtree', system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;
  --tbl-font-sans-compact: 'Figtree', system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;

  /* Figtree weight scale */
  --tw-body:   500;
  --tw-medium: 600;
  --tw-semi:   700;
  --tw-bold:   800;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--tbl-font-sans);
  font-weight: var(--tw-body);
  color: var(--tbl-text-body);
  /* Transparent so the chart inherits the host page's background when embedded in an iframe
     (e.g. publications with non-white backgrounds). Standalone, the browser default (white)
     shows through, so the gallery view is visually unchanged. */
  background: transparent;
  line-height: 1.5;
}

/* =========================================================================
 * Figure card
 * ========================================================================= */
.figure-card {
  margin-bottom: 28px;
  /* Query container so narrow-width rules (e.g. stacking the download buttons) respond to
     the CHART CARD's own width, not the page viewport — correct for an embed of any size,
     unlike AILMT's viewport media query (which keyed on its full sidebar+main layout). */
  container-type: inline-size;
}
.figure-card:last-child { margin-bottom: 0; }

/* Eyebrow above the title (e.g. "Figure 1"). Ported from the tracker's figure-supertitle. */
.figure-supertitle {
  font: var(--tw-body) 11px/1.2 var(--tbl-font-sans);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--tbl-text-muted);
  margin: 0 0 8px;
}

.figure-title {
  margin: 0 0 4px;
  font-size: 18px;
  font-weight: var(--tw-bold);
  color: var(--tbl-navy);
  line-height: 1.25;
  letter-spacing: -0.005em;
}

.figure-subtitle {
  margin: 0 0 10px;
  font-size: 13px;
  font-weight: var(--tw-semi);
  color: var(--tbl-text-muted);
}

/* Inline title selector (spec title_selectors): a button+popover widget embedded in the title
   text. Ported verbatim (design + rules) from the AI Labor Market Tracker's
   .inline-select-wrap/.inline-select/.inline-select-caret/.inline-select-popover (styles.css
   L392-479) — the industry-picker control. Looks like the surrounding title text (same font,
   weight, color, size); a thin outline + caret signal interactivity. */
.inline-select-wrap {
  position: relative;
  display: inline-block;
}
.inline-select {
  appearance: none;
  background: transparent;
  border: 1px solid var(--tbl-border);
  border-radius: 4px;
  /* Inherit type from the surrounding .figure-title so the only visible difference is the
     outline (and, when the active option resolves a color, the label tint). */
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  padding: 0 6px 0 8px;
  margin: 0 1px;
  cursor: pointer;
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  line-height: 1.15;
  transition: border-color 0.12s, background 0.12s;
}
.inline-select:hover,
.inline-select:focus-visible {
  border-color: var(--tbl-navy);
  background: var(--tbl-bg-subtle);
  outline: none;
}
.inline-select[aria-expanded="true"] {
  border-color: var(--tbl-navy);
  background: var(--tbl-bg-subtle);
}
.inline-select-caret {
  font-size: 0.7em;
  color: var(--tbl-text-muted);
  margin-left: 2px;
}

/* Popover listbox under the inline-select button. */
.inline-select-popover {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  margin: 0;
  padding: 4px 0;
  list-style: none;
  background: var(--tbl-bg);
  border: 1px solid var(--tbl-border);
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
  z-index: 100;
  min-width: 100%;
  max-width: 360px;
  font-family: var(--tbl-font-sans);
  font-size: 14px;
  font-weight: var(--tw-body);
  letter-spacing: normal;
  color: var(--tbl-text-body);
  white-space: nowrap;
}
.inline-select-popover li {
  padding: 6px 14px;
  cursor: pointer;
  outline: none;
}
.inline-select-popover li:hover,
.inline-select-popover li:focus {
  background: var(--tbl-bg-subtle);
  color: var(--tbl-text-heading);
}
.inline-select-popover li.is-active {
  color: var(--tbl-navy);
  font-weight: var(--tw-semi);
}

/* =========================================================================
 * Legend slot + canvas
 * ========================================================================= */
.figure-legend-slot { width: 100%; }

/* Right-legend layout: flex row containing the scroll wrapper (left) and the vertical
   legend column (right). The chart area gets a reduced width so the legend column has
   space — no layout feedback loop because the width computation is based on the OUTER
   card element, not this flex child. */
.figure-body--legend-right {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 16px;
}
/* The canvas scroll wrapper stretches to fill the remaining flex space. */
.figure-body--legend-right .figure-canvas-scroll {
  flex: 1 1 0;
  min-width: 0;
}
/* Right legend column: fixed width matching LEGEND_COLUMN_WIDTH in render-live.ts (160px).
   Centered vertically on the chart area. ~22px row gaps per Style-Guide §8.2. */
.figure-legend-slot--right {
  flex: 0 0 160px;
  width: 160px;
  align-self: center;
}
/* Vertical legend: items stacked in a column with consistent row spacing. Items stretch
   to the column width and left-align their contents, so every swatch sits on a common
   left edge (Fix #D). */
.tbl-legend--vertical {
  flex-direction: column;
  align-items: stretch;
  gap: 0 0;
  row-gap: 4px;
  margin: 0;
  min-height: 0;
}
.tbl-legend--vertical .tbl-legend-item {
  justify-content: flex-start;
  text-align: left;
  width: 100%;
}
/* Reset button left-aligned at the bottom of the vertical legend (no trailing right
   margin pushing it off the common left edge). */
.tbl-legend--vertical .tbl-legend-reset {
  margin: 2px 0 0 0;
  align-self: flex-start;
}
/* The vertical (right) legend is vertically centered on the chart, so the reset button
   appearing/disappearing must NOT change the column height (that would re-center and shift
   every row). Reserve its slot always: keep it in flow but invisible until pinned (overrides
   the global display:none for the hidden state). */
.tbl-legend--vertical .tbl-legend-reset[hidden] {
  display: inline-flex;
  visibility: hidden;
}

/* Small-multiples PER-PANE grid: a responsive CSS grid of mini-chart cells. The live layer
   sets --figure-cols (reflowed by container width) and re-renders each pane's SVG at the
   matching pane width. Each cell stacks a pane title above its mini-SVG. */
.figure-grid {
  display: grid;
  grid-template-columns: repeat(var(--figure-cols, 2), minmax(0, 1fr));
  gap: 18px 16px;
  width: 100%;
}
/* Horizontal-bar and variable-width figures never reflow their panes to extra rows; when they
   don't fit, this wrapper scrolls horizontally instead (the grid takes its natural width). */
.figure-grid-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.figure-grid-scroll > .figure-grid {
  width: max-content;
}
.figure-pane {
  min-width: 0;
}
.figure-pane-title {
  font-size: 11px;
  font-weight: 700;
  color: var(--tbl-text-heading);
  margin: 0 0 2px 0;
}
.figure-pane svg {
  display: block;
  max-width: 100%;
}

/* Scroll wrapper isolates horizontal overflow to the chart region, so the title/subtitle/
   source above and below keep wrapping to the card width. */
.figure-canvas-scroll {
  width: 100%;
  position: relative;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.figure-canvas {
  width: 100%;
  position: relative;
}
/* Native px: the SVG is re-rendered at the container width and keeps that exact width; below
   the min width it overflows into the scroll wrapper rather than being CSS-scaled down. */
.figure-canvas svg {
  display: block;
  max-width: none;
}

/* Sticky y-axis overlay — floating value labels pinned at the left during horizontal scroll
   (the controller translateX's it by scrollLeft). */
.figure-y-axis-overlay {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  pointer-events: none;
}
.figure-y-axis-overlay span {
  position: absolute;
  left: 0;
  background: rgba(255, 255, 255, 0.8);
  padding: 1px 4px;
  border-radius: 6px;
  font: var(--tw-body) 10.5px/1 var(--tbl-font-sans);
  color: var(--tbl-text-axis);
  white-space: nowrap;
}

/* X-axis title — sticky + centered in the visible viewport regardless of horizontal scroll. */
/* X- and y-axis titles share one type treatment (12px semibold, axis color); they differ only
 * in placement — x centered below the plot, y left-aligned above it. The negative top margin on
 * the x-title absorbs the SVG's bottom whitespace below the tick labels so the title sits close
 * to them (not floating well below). */
.figure-x-axis-title {
  position: sticky;
  left: 0;
  margin: -3px 0 0;
  font: var(--tw-semi) 12px/1.3 var(--tbl-font-sans);
  color: var(--tbl-text-axis);
  text-align: center;
}
/* Scatter's numeric x-axis labels sit tighter to the frame than the temporal axis the default
   was tuned for, so give the x-axis title a little more breathing room. */
.chart-scatter .figure-x-axis-title {
  margin-top: 8px;
}
.figure-y-axis-title {
  margin: 0 0 4px;
  font: var(--tw-semi) 12px/1.3 var(--tbl-font-sans);
  color: var(--tbl-text-axis);
  text-align: left;
}

/* =========================================================================
 * Meta / source line
 * ========================================================================= */
.figure-meta {
  margin-top: 10px;
  font-size: 12px;
  color: var(--tbl-text-muted);
  line-height: 1.45;
  display: flex;
  align-items: flex-start;
  gap: 16px;
}
.figure-meta-text { flex: 1 1 auto; min-width: 0; }
.figure-meta .figure-note { margin: 0 0 4px; }
.figure-meta .figure-source { margin: 0; }
.figure-meta .figure-source-prefix { font-weight: var(--tw-semi); }

/* =========================================================================
 * Legend
 * ========================================================================= */
.tbl-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 4px;
  margin: 0 0 8px;
  padding: 0;
  /* Reserve the reset button's height (22px) so the row doesn't grow â€” and shove the
     chart down ~1px â€” when the reset toggles in on the first pin. */
  min-height: 22px;
}
.tbl-legend-item {
  appearance: none;
  background: transparent;
  border: none;
  padding: 4px 8px 3px 6px;
  margin: 0;
  font: var(--tw-body) 12px/1.2 var(--tbl-font-sans-compact, var(--tbl-font-sans));
  color: var(--tbl-text-body);
  display: inline-flex;
  align-items: center;
  gap: 7px;
  cursor: pointer;
  border-radius: 4px;
  box-shadow: inset 0 -2px 0 transparent;
  transition: background 0.12s, color 0.12s, box-shadow 0.12s;
}
.tbl-legend-item:hover,
.tbl-legend-item:focus-visible {
  background: var(--tbl-bg-subtle);
  color: var(--tbl-text-heading);
  outline: none;
}
.tbl-legend-item.is-pinned {
  color: var(--tbl-text-heading);
  background: var(--tbl-bg-subtle);
  box-shadow: inset 0 -1px 0 var(--legend-color, var(--tbl-navy));
}
.tbl-legend-swatch {
  width: 18px;
  height: 3px;
  border-radius: 1px;
  display: inline-block;
  flex-shrink: 0;
}
.tbl-legend-swatch.is-dashed {
  background: linear-gradient(
    to right,
    var(--swatch-color, currentColor) 0 25%,
    transparent          25% 37.5%,
    var(--swatch-color, currentColor) 37.5% 62.5%,
    transparent          62.5% 75%,
    var(--swatch-color, currentColor) 75% 100%
  );
  border: 0;
  height: 2px;
}
.tbl-legend-swatch.is-rect {
  width: 14px;
  height: 12px;
  border-radius: 1px;
}
.tbl-legend-swatch.is-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #fff;
  box-shadow: inset 0 0 0 1.5px #000;
}
/* Line + point-marker swatch: sized to the inline SVG (line with the series' symbol). */
.tbl-legend-swatch.is-symbol {
  width: 22px;
  height: 12px;
  border-radius: 0;
  background: none;
  display: inline-flex;
  align-items: center;
}
/* Point-chart swatch: a filled colored marker (the symbol) with no connecting line. */
.tbl-legend-swatch.is-point {
  width: 18px;
  height: 16px;
  border-radius: 0;
  background: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* Two-group (color + shape) point legend: groups STACK on separate lines (color row, then
   shape row), each group an inline cluster of swatches. */
.tbl-legend--grouped {
  flex-direction: column;
  align-items: flex-start;
  gap: 2px 0;
}
.tbl-legend-group {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 4px;
}
.tbl-legend-group-title {
  font: var(--tw-semi, 600) 11px/1.2 var(--tbl-font-sans-compact, var(--tbl-font-sans));
  color: var(--tbl-text-muted, var(--tbl-text-axis));
  text-transform: none;
  margin-right: 2px;
  white-space: nowrap;
}
/* Shape-legend rows are non-interactive in v1: plain markers + labels, no hover affordance. */
.tbl-legend-item.is-static {
  cursor: default;
  padding: 4px 8px 3px 6px;
}
.tbl-legend-item.is-static:hover {
  background: transparent;
  color: var(--tbl-text-body);
}

/* =========================================================================
 * Legend reset button
 * ========================================================================= */
.tbl-legend-reset {
  appearance: none;
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid var(--tbl-border);
  background: var(--tbl-bg);
  color: var(--tbl-text-muted);
  margin: 0 6px 0 0;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
  font-family: 'Segoe UI Symbol', 'Apple Symbols', 'Noto Sans Symbols', system-ui, sans-serif;
  font-size: 16px;
  line-height: 1;
  text-align: center;
}
.tbl-legend-reset-icon {
  display: block;
  transform: translateY(-2px);
  line-height: 1;
}
.tbl-legend-reset[hidden] { display: none; }
.tbl-legend-reset:hover,
.tbl-legend-reset:focus-visible {
  background: var(--tbl-navy);
  color: #fff;
  border-color: var(--tbl-navy);
  outline: none;
}

/* =========================================================================
 * Hover-to-dim
 * ========================================================================= */
/* Applies to line <path data-series> AND bar/stacked <rect data-series>. Scoped to the chart
   regions — the single-chart canvas AND the per-pane small-multiples grid — so dimming works
   for figures too (the grid svgs live in .figure-grid, not .figure-canvas). */
.figure-canvas svg [data-series],
.figure-grid svg [data-series] {
  transition: opacity 120ms linear;
}
.figure-canvas svg .tbl-dimmed,
.figure-grid svg .tbl-dimmed {
  opacity: 0.15;
}
/* The diverging net-total LABEL is a wide text over the bar center; it is tagged with the
   Total key so it DIMS with the dot, but it must not steal clicks from the segments beneath
   it. Make it non-interactive so clicks fall through to the segment — only the small net
   DOT (tbl-net-marker) selects Total. */
.figure-canvas svg .tbl-net-label,
.figure-grid svg .tbl-net-label {
  pointer-events: none;
}

/* =========================================================================
 * Click-to-select cursor — only on interactive (has-legend) charts.
 * render-live adds .is-selectable to the card when it wires chart clicks to the
 * legend's pin toggle. The transparent crosshair hit-overlay sits ON TOP of the
 * marks, so its cursor wins where they overlap; give it the same pointer cursor so the
 * affordance is consistent across the whole plot when selection is on.
 * ========================================================================= */
.figure-card.is-selectable .figure-canvas svg [data-series],
.figure-card.is-selectable .figure-canvas svg .tbl-crosshair-hit,
.figure-card.is-selectable .figure-canvas svg .tbl-band-crosshair-hit,
.figure-card.is-selectable .figure-grid svg [data-series],
.figure-card.is-selectable .figure-grid svg .tbl-crosshair-hit,
.figure-card.is-selectable .figure-grid svg .tbl-band-crosshair-hit {
  cursor: pointer;
}

/* =========================================================================
 * Crosshair tooltip â€” frosted glass
 * ========================================================================= */
.tbl-tooltip {
  position: fixed;
  pointer-events: none;
  opacity: 0;
  background: rgba(255, 255, 255, 0.5);
  color: var(--tbl-text-heading, #1A1A2E);
  font: var(--tw-body) 12px/1.35 var(--tbl-font-sans);
  padding: 8px 10px;
  border-radius: 6px;
  border: 1px solid rgba(200, 205, 215, 0.7);
  white-space: nowrap;
  z-index: 9999;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.10);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
          backdrop-filter: blur(20px) saturate(160%);
  transition: opacity 80ms linear;
  max-width: 320px;
}
.tbl-tooltip-head {
  margin-bottom: 4px;
  font-weight: var(--tw-bold);
}
.tbl-tooltip-label { font-weight: var(--tw-body); }
.tbl-tooltip-value { font-weight: var(--tw-bold); }
.tbl-tooltip-row {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 2px;
}
.tbl-tooltip-row:last-child { margin-bottom: 0; }
.tbl-tooltip-swatch {
  display: inline-block;
  flex-shrink: 0;
  width: 18px;
  height: 3px;
  border-radius: 1px;
}
.tbl-tooltip-swatch.is-dashed {
  background: linear-gradient(
    to right,
    var(--swatch-color, currentColor) 0 25%,
    transparent          25% 37.5%,
    var(--swatch-color, currentColor) 37.5% 62.5%,
    transparent          62.5% 75%,
    var(--swatch-color, currentColor) 75% 100%
  );
  height: 2px;
}
/* Total row (diverging net dot): a CIRCLE swatch matching the net marker + legend "Total"
   entry — white fill, black inset stroke. Mirrors .tbl-legend-swatch.is-dot. */
.tbl-tooltip-swatch.is-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #fff;
  box-shadow: inset 0 0 0 1.5px #000;
}
/* Bar tooltip swatch: a filled square matching the bar legend (vs the default thin line). */
.tbl-tooltip-swatch.is-square {
  width: 11px;
  height: 11px;
  border-radius: 1px;
}
/* Scatter tooltip header: the point's actual marker symbol (colored), inline before the text. */
.tbl-tooltip-swatch.is-symbol {
  width: 16px;
  height: 14px;
  background: none;
  border-radius: 0;
  vertical-align: middle;
  margin-right: 5px;
}

/* =========================================================================
 * Figure header — flex row with title-text left, logo right
 * ========================================================================= */
.figure-header {
  margin-bottom: 0;
}
/* Title row: the title fills the width and pushes the logo to the right; baseline alignment
   lets the logo sit on the title's first-line baseline. The eyebrow sits above this row and
   the subtitle below it (both full width). */
.figure-titlebar {
  position: relative;
}
.figure-titlebar .figure-title {
  /* Reserve space on the right for the absolutely-positioned logo (130px + ~16px gap) so
     the title text wraps before it. */
  padding-right: 146px;
}

/* =========================================================================
 * Logo
 * ========================================================================= */
.figure-logo {
  position: absolute;
  right: 0;
  /* Lift the logo so its wordmark baseline (~0.87 down the 4:1 box ≈ 28.3px at 130px wide)
     lands on the title's first-line baseline (~17px below the titlebar top for the 18px/1.25
     title): top = 17 − 28.3 ≈ −11.3px. Absolute + inside the relative titlebar, so it adds
     no row height (no eyebrow gap) and its bottom (≈21px) stays within the title's first line
     — nothing overflows downward, so no Firefox clip. */
  top: -11.3px;
  width: 130px;
}
.figure-logo svg {
  display: block;
  width: 100%;
  height: auto;
}

/* =========================================================================
 * Download buttons — ported from tracker styles.css
 * ========================================================================= */
.figure-downloads {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}
.figure-download-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font: var(--tw-medium) 12px/1 var(--tbl-font-sans);
  color: var(--tbl-text-muted);
  background: transparent;
  border: 1px solid var(--tbl-border);
  border-radius: 4px;
  padding: 4px 8px;
  cursor: pointer;
  white-space: nowrap;
}
.figure-download-btn:hover,
.figure-download-btn:focus-visible {
  border-color: var(--tbl-navy);
  color: #fff;
  background: var(--tbl-navy);
  outline: none;
}
.figure-download-btn:disabled {
  opacity: 0.6;
  cursor: default;
}
.figure-download-btn svg { display: block; flex-shrink: 0; }

/* =========================================================================
 * Responsive — stack the Data/Image buttons when the chart card itself is narrow.
 * Container query (keyed on the card width), so it's correct regardless of the embed's
 * page context. ~520px ≈ AILMT's chart-area width when it stacked (880px viewport − 280px
 * sidebar − gaps/padding).
 * ========================================================================= */
@container (max-width: 520px) {
  .figure-downloads { flex-direction: column; }
}

/* =========================================================================
 * Table — .tbl-table (figure type "table")
 * Uses --tbl-* tokens throughout; no hardcoded hex values.
 * ========================================================================= */

/* ---- Table element ---- */
.tbl-table {
  font-family: var(--tbl-font-sans);
  font-weight: var(--tw-body);
  font-size: 13px;
  color: var(--tbl-text-body);
  border-collapse: collapse;
  table-layout: fixed;
  width: 100%;
}

/* ---- Multi-pane: stacked sub-tables, each with its own subheading ---- */
.tbl-pane { margin-top: 20px; }
.tbl-pane:first-of-type { margin-top: 8px; }
.tbl-pane-title {
  font-family: var(--tbl-font-sans);
  font-weight: var(--tw-bold);
  color: var(--tbl-text-heading);
  font-size: 15px;
  margin: 0 0 8px;
}

/* ---- Column sizing via colgroup/col ---- */
.tbl-table col { }

/* ---- Header ---- */
.tbl-table thead th {
  font-weight: var(--tw-bold);
  color: var(--tbl-text-heading);
  font-size: 12px;
  padding: 6px 8px;
  background: var(--tbl-bg);
  text-align: center;
  vertical-align: bottom;
  white-space: nowrap;
}

/* Header→body separator: every header cell whose bottom edge is the header base, so the rule
   stays continuous across rowspanning cells (stub corner, blank-group data columns). */
.tbl-table thead th.is-header-bottom {
  border-bottom: 1px solid var(--tbl-axis-stroke);
}

/* Banner tiers (non-leaf header rows): centered. Inter-tier rules are OFF by default; they are
   drawn only when the table has .tbl-table--header-tier-rules (spec header_tier_rules: true). */
.tbl-table thead tr:not(:last-child) th {
  vertical-align: middle;
}
.tbl-table.tbl-table--header-tier-rules thead tr:not(:last-child) th {
  border-bottom: 1px solid var(--tbl-border);
}

/* Leaf headers (last header row): bottom-aligned, centered (inherits text-align:center). */
.tbl-table thead tr:last-child th {
  vertical-align: bottom;
}

/* Leaf-header line clamp (header_max_lines): wrap the label to N lines, ellipsis-free overflow
   hidden. The clamp lives on an INNER span (not the th) so the webkit-box display does not drop
   the table cell box and break column alignment. --tbl-header-lines is set per-span. */
.tbl-table thead th .tbl-table-header-clamp {
  white-space: normal;
  display: -webkit-box;
  -webkit-line-clamp: var(--tbl-header-lines, 2);
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Banner cells (colSpan > 1): centered label flanked by hairline rules extending to the cell's
   edges, showing the columns the banner governs. Leaf headers (colSpan 1) are unaffected. */
.tbl-table thead th.is-spanner { text-align: center; }
.tbl-table thead th.is-spanner > .tbl-table-spanner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.tbl-table thead th.is-spanner > .tbl-table-spanner::before,
.tbl-table thead th.is-spanner > .tbl-table-spanner::after {
  content: "";
  flex: 1 1 auto;
  border-top: 1px solid var(--tbl-border);
}

/* Stub cell in header (corner) — left-aligned. The corner <th> carries class
   tbl-table-stub-header in the rendered HTML. */
.tbl-table thead th.tbl-table-stub-header {
  text-align: left;
}

/* Leaf header over a text column — left-aligned to match its left-aligned cells. */
.tbl-table thead th.is-text {
  text-align: left;
}

/* ---- Sub-label: displayed on its own line below the leaf header text ---- */
.tbl-table-sublabel {
  display: block;
  font-size: 10px;
  font-weight: var(--tw-body);
  color: var(--tbl-text-muted);
  margin-top: 2px;
  white-space: nowrap;
}

/* ---- Body ---- */
.tbl-table tbody td,
.tbl-table tbody th {
  padding: 5px 8px;
  border-bottom: 1px solid var(--tbl-gridline);
  font-size: 13px;
  background: var(--tbl-bg);
  /* Base of the sticky stacking ladder: scrolling body cells sit below the sticky thead (z 2)
     and the pinned first column (z 3) / header corner (z 4). */
  position: relative;
  z-index: 0;
}

/* Numeric cells: centered by default, tabular figures. */
td.is-num {
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* Text cells: left-aligned, wrapping (for prose values like notes/descriptions). */
td.is-text {
  text-align: left;
  white-space: normal;
  overflow-wrap: break-word;
}

/* column_wrap: force a data column's body cells to wrap within their (fixed) width, regardless of
   whether the column is text- or number-typed. Mirrors the stub's .is-wrap. */
td.is-wrap {
  white-space: normal;
  overflow-wrap: break-word;
}

/* Stub (row label) cells: left-aligned. */
th.tbl-table-stub {
  text-align: left;
  font-weight: var(--tw-body);
  color: var(--tbl-text-body);
}

/* Stub on one line. By default the column is sized to the longest label so nothing is clipped;
   when capped narrower (stub_max_width / stub_width) the label is clipped to the column. The clip
   lives on an inner block (table cells don't honor overflow) — see .tbl-table-stub-clip. */
th.tbl-table-stub.is-nowrap,
.tbl-table-group-inner.is-nowrap {
  white-space: nowrap;
}
/* stub_wrap: allow the row label to wrap onto multiple lines within the (capped) column. */
th.tbl-table-stub.is-wrap {
  white-space: normal;
  overflow-wrap: break-word;
}
/* Inner clip box for a non-wrapping stub label (table cells ignore overflow, so the cell content
   is wrapped in this block which does clip). */
.tbl-table-stub.is-nowrap > .tbl-table-stub-clip {
  display: block;
  overflow: hidden;
  white-space: nowrap;
}

/* ---- Row groups ---- */
/* Group heading: bold, no fill. A single hairline rule ABOVE the heading separates groups;
   extra top padding gives breathing room (the rule + space does the grouping, not a fill band). */
tr.tbl-table-group th,
tr.tbl-table-group td {
  text-align: left;
  font-weight: var(--tw-bold);
  color: var(--tbl-text-heading);
  border-top: 1px solid var(--tbl-border);
  padding-top: 14px;
  padding-bottom: 3px;
}
/* The first group has no rows above it, so its top rule is redundant — drop it. */
.tbl-table tbody tr.tbl-table-group:first-child th,
.tbl-table tbody tr.tbl-table-group:first-child td {
  border-top: none;
  padding-top: 4px;
}
/* Keep the group title anchored at the left during horizontal scroll (it labels the pinned
   rows), instead of scrolling off and clipping under the sticky first column. Gated on the SAME
   sticky-first flag as the row stubs, so the two behave consistently — without it, a group title
   would pin while its row labels scrolled, which reads as a bug. */
.tbl-table--sticky-first .tbl-table-group-inner {
  position: sticky;
  /* Pin at the cell's 8px left padding — its natural rest position — so it does NOT visibly shift
     left before sticking, and stays aligned with the stub label text (also indented 8px). */
  left: 8px;
  display: inline-block;
}

/* ---- Collapsible row groups ---- */
/* The group label becomes a real <button> (keyboard/aria operable) with a caret inline-left.
   No button chrome: it inherits the group heading's font/color so a collapsible table's group
   headers look identical to a plain one, plus the caret affordance. */
.tbl-table-group-toggle {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.tbl-table-group-toggle:focus-visible {
  outline: 2px solid var(--tbl-navy);
  outline-offset: 2px;
}
/* Caret: a small CSS triangle. Points RIGHT when collapsed; rotates to point DOWN when the
   group is expanded (aria-expanded is the source of truth; mount.ts also mirrors it onto an
   is-collapsed class). */
.tbl-table-caret {
  flex-shrink: 0;
  width: 0;
  height: 0;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  border-left: 5px solid currentColor;
  transform: rotate(0deg);
  transition: transform 0.12s ease;
}
.tbl-table-group-toggle[aria-expanded="true"] .tbl-table-caret {
  transform: rotate(90deg);
}
/* Rows hidden by a collapsed group use the hidden attribute; enforce display:none in case a
   display rule elsewhere would otherwise resurrect them. */
.tbl-table tr[hidden] { display: none; }
/* Expand/collapse-all control. Marker class .tbl-table-collapse-all is always present (tests/tools
   find the control by it). Placement chrome is added by the caller: in the footer action row it
   takes .figure-download-btn; in the stub-header corner (default) it takes the compact corner
   chrome below — a small muted text button seated at the bottom-left of the corner cell (the
   corner <th>'s vertical-align:bottom + text-align:left do the seating, so on a multi-tier header
   it aligns to the leaf header row), beside the carets it toggles. */
.tbl-table-collapse-all-corner {
  appearance: none;
  display: inline-block;
  font: var(--tw-medium) 11px/1 var(--tbl-font-sans);
  color: var(--tbl-text-muted);
  background: transparent;
  border: 1px solid var(--tbl-border);
  border-radius: 4px;
  padding: 2px 6px;
  margin-top: 4px;
  cursor: pointer;
  white-space: nowrap;
}
.tbl-table-collapse-all-corner:hover,
.tbl-table-collapse-all-corner:focus-visible {
  border-color: var(--tbl-navy);
  color: #fff;
  background: var(--tbl-navy);
  outline: none;
}

/* Group note: italic, muted, smaller — sits directly under the heading, no rule, no fill. */
tr.tbl-table-group-note th,
tr.tbl-table-group-note td,
.tbl-table-group-note {
  text-align: left;
  font-style: italic;
  font-weight: var(--tw-body);
  font-size: 11px;
  color: var(--tbl-text-muted);
  padding-top: 0;
  padding-bottom: 6px;
}

/* ---- Emphasis ---- */
.is-emphasis {
  font-weight: var(--tw-bold);
  background: var(--tbl-bg-subtle) !important;
}
/* th.tbl-table-stub (0,1,1) otherwise outranks .is-emphasis (0,1,0) on font-weight (its background
   already wins via !important), so a whole-row-emphasized stub needs its own higher-specificity
   bold rule to match the row's value cells. */
th.tbl-table-stub.is-emphasis {
  font-weight: var(--tw-bold);
}

/* ---- Positive / negative coloring ---- */
/* Use categorical green (cat4) and red (cat5) tokens — muted base tones. */
td.is-pos {
  color: var(--tbl-cat4);  /* green */
}
td.is-neg {
  color: var(--tbl-cat5);  /* red */
}

/* ---- Row hover (CSS only — no JS needed) ---- */
.tbl-table tbody tr:hover td,
.tbl-table tbody tr:hover th {
  background: var(--tbl-bg-subtle);
}

/* ---- Column hover (JS toggles .is-col-hover on [data-col=k] cells) ---- */
/* Same subtle grey as the row hover so the crosshair reads gently, not as a bold blue band. */
.tbl-table .is-col-hover {
  background: var(--tbl-bg-subtle) !important;
}

/* ---- Sticky first column ---- */
/* Enabled when .tbl-table--sticky-first is present on the table element. The pinned stub column
   and its header corner are positioned (sticky) so they paint ABOVE the static, scrolling header
   + body cells — column headers are clipped by the pinned column at the same moment their data
   cells slide under it:
     body cells         z 0  (set above)
     sticky stub column z 3  (body stub cells + leaf-tier stub <th>)
     header corner      z 4  (the rowspanning corner, pinned left). */
.tbl-table--sticky-first td:first-child,
.tbl-table--sticky-first th.tbl-table-stub {
  position: sticky;
  left: 0;
  z-index: 3;
  /* Opaque background so scrolling cells pass behind the pinned column. */
  background: var(--tbl-bg);
}
/* The header corner is pinned at the left and must sit above the scrolling thead so header cells
   disappear under it in lockstep with their data column. */
.tbl-table--sticky-first thead th.tbl-table-stub-header {
  position: sticky;
  left: 0;
  z-index: 4;
  background: var(--tbl-bg);
}

/* ---- Disable the sticky first column at phone widths ---- */
/* Below ~420px a pinned stub eats too much of the viewport, leaving the data columns cramped and
   illegible. Drop the horizontal pin (left:auto neutralizes the sticky constraint) so the whole
   table scrolls freely. */
@media (max-width: 419px) {
  .tbl-table--sticky-first td:first-child,
  .tbl-table--sticky-first th.tbl-table-stub,
  .tbl-table--sticky-first thead th.tbl-table-stub-header,
  .tbl-table--sticky-first .tbl-table-group-inner {
    left: auto;
  }
}

/* ---- Footnote definition list ---- */
/* Rendered after the table by mount.ts when the spec has footnotes. Small + muted, one line per
   footnote (a leading <sup> marker, then the text). */
.tbl-table-footnotes {
  margin-top: 8px;
  font-size: 11px;
  line-height: 1.4;
  color: var(--tbl-text-muted);
}

/* ---- Footnote superscript ---- */
.tbl-table sup {
  font-size: 0.7em;
  vertical-align: super;
  line-height: 0;
  color: var(--tbl-text-muted);
}

/* ---- Inline math: sub/superscripts + stacked sub+super ---- */
/* Math scripts (from ( … ) markup) inherit the cell's text color — overriding the muted
   footnote <sup> styling above — and use a slightly smaller size. */
.tbl-table sup.tbl-math,
.tbl-table sub.tbl-math {
  font-size: 0.72em;
  line-height: 0;
  color: inherit;
}
.tbl-table sup.tbl-math { vertical-align: super; }
.tbl-table sub.tbl-math { vertical-align: sub; }
/* Stacked sub+super (e.g. 	heta_1^K → θ with K above, 1 below): a tight inline column placed
   right after the base glyph, sized down like a script and left-aligned so digits/letters of
   different widths share a common left edge. */
.tbl-table .tbl-msubsup {
  display: inline-flex;
  flex-direction: column;
  /* Center the two-line stack on the text's midline so the super sits at cap height and the
     sub just below the baseline (rather than the whole stack dropping below it). */
  vertical-align: middle;
  line-height: 1;
  font-size: 0.72em;
  text-align: left;
}
