/* ============================================
   Fonts
   ============================================ */
@font-face {
  font-family: "Britti Sans";
  src: url("fonts/BrittiSans-Semibold.otf") format("opentype");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* ============================================
   Tokens
   ============================================ */
:root {
  /* Surfaces — tinted just barely toward the brand purple */
  --bg:            oklch(0.965 0.004 280);
  --card:         #ffffff;
  --card-2:        oklch(0.985 0.002 280);
  --hairline:      oklch(0.92 0.006 280);
  --hairline-2:    oklch(0.94 0.006 280);

  /* Text */
  --ink:           oklch(0.20 0.012 280);
  --ink-2:         oklch(0.42 0.008 280);
  --ink-3:         oklch(0.58 0.006 280);
  --ink-mute:      oklch(0.70 0.005 280);

  /* Brand */
  --brand:         oklch(0.55 0.215 282);     /* primary purple */
  --brand-strong:  oklch(0.50 0.235 282);     /* line, dot */
  --brand-soft:    oklch(0.92 0.04  282);     /* slider track */
  --brand-halo:    oklch(0.62 0.18  282 / 0.28);

  /* Chart */
  --grid:          oklch(0.93 0.005 280);
  --divider:       oklch(0.84 0.006 280);

  /* Status */
  --up:            oklch(0.62 0.16  152);

  /* Spacing scale */
  --s-2: 4px; --s-3: 6px; --s-4: 8px; --s-5: 12px;
  --s-6: 16px; --s-7: 20px; --s-8: 24px; --s-9: 32px;
  --s-10: 48px; --s-11: 64px;

  /* Radii */
  --r-card: 14px;
  --r-chip: 10px;
  --r-pill: 999px;

  /* Shadows — calibrated soft */
  --shadow-card:
    0 0.5px 1px oklch(0.20 0.01 280 / 0.04),
    0 6px 18px oklch(0.20 0.01 280 / 0.05),
    0 22px 40px -18px oklch(0.20 0.01 280 / 0.08);
  --shadow-card-elev:
    0 0.5px 1px oklch(0.20 0.01 280 / 0.05),
    0 8px 24px oklch(0.20 0.01 280 / 0.06),
    0 26px 60px -22px oklch(0.20 0.01 280 / 0.10);

  --font: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* ============================================
   Reset / base
   ============================================ */
*,*::before,*::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
/* Color scheme is explicitly light — without this, Chromium applies a subtle
   gray tint to iframes whose document doesn't declare one, which on a
   colored Framer canvas reads as "the iframe background isn't really
   transparent." */
html { color-scheme: light; }
/* Default to transparent so the iframe embed has nothing opaque to paint
   even before any JS runs (avoids a one-frame off-white flash that Framer
   sometimes captures). Standalone gets its tinted background back via the
   :not(.is-embedded) selector below. */
body {
  font-family: var(--font);
  background: transparent;
  color: var(--ink);
  font-feature-settings: "ss01", "cv01", "cv11";
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100vh;
}
html:not(.is-embedded) body { background: var(--bg); }
/* Embedded mode (e.g. Framer iframe): strip page chrome — transparent bg,
   no scrollbars, body sized to viewport so only the stage is visible. */
html.is-embedded { background: transparent; overflow: hidden; }
html.is-embedded body { background: transparent; overflow: hidden; min-height: 0 !important; height: 100vh; }
html.is-embedded .fit { min-height: 100vh; padding: 0; }
button { font: inherit; color: inherit; }

/* ============================================
   Stage / page layout — fixed size, scaled as a whole
   ============================================ */
body { overflow-x: hidden; }

.fit {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  width: 100%;
  min-height: 100vh;
  padding: 24px 0;
  box-sizing: border-box;
}

.stage {
  position: relative;
  width: 1080px;
  flex-shrink: 0;
  transform-origin: top center;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto auto;
  column-gap: 20px;
  row-gap: 20px;
  align-items: start;
  padding: 56px 24px;
  box-sizing: border-box;
}

/* ============================================
   Prompt card (top-left)
   ============================================ */
.prompt-card {
  grid-column: 1;
  grid-row: 1;
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card-elev);
  padding: 18px 22px 22px;
  max-width: 470px;
  width: 100%;
  position: relative;
  z-index: 1;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 480ms cubic-bezier(0.22, 1, 0.36, 1),
              transform 480ms cubic-bezier(0.22, 1, 0.36, 1);
}
.prompt-card.is-in { opacity: 1; transform: translateY(0); }
.prompt-card__header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 22px 14px;          /* match card horizontal padding */
  margin: 0 -22px 18px;          /* extend the divider to the card edges */
  border-bottom: 1px solid var(--hairline);
}
.prompt-card__icon {
  display: block;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
}
.prompt-card__title {
  font-weight: 600;
  font-size: 18px;
  letter-spacing: -0.012em;
  color: var(--ink);
}
.prompt-card__text {
  margin: 0;
  font-size: 18px;
  line-height: 1.45;
  font-weight: 500;
  color: var(--ink);
  letter-spacing: -0.012em;
  min-height: calc(1.45em * 2);   /* reserve two lines so layout doesn't jump while typing */
}
.prompt-card__typed { white-space: pre-wrap; }
.prompt-card__caret {
  display: inline-block;
  width: 1px;
  height: 1.05em;
  vertical-align: -2px;
  margin-left: 2px;
  background: var(--ink);
  animation: blink 1s steps(1) infinite;
}
@keyframes blink { 50% { opacity: 0; } }

/* ============================================
   Segmented (top-right)
   ============================================ */
.segmented {
  grid-column: 2;
  grid-row: 1;
  align-self: end;
  margin-bottom: 32px;
  margin-right: 15px;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px;
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-card-elev);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 520ms cubic-bezier(0.22, 1, 0.36, 1),
              transform 520ms cubic-bezier(0.22, 1, 0.36, 1);
}
.segmented.is-in { opacity: 1; transform: translateY(0); }
.segmented__btn {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 8px 16px;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  border-radius: var(--r-pill);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: color 160ms ease, background-color 220ms ease;
}
.segmented__icon {
  width: 16px;
  height: 16px;
  display: inline-block;
  background-color: currentColor;          /* recolored to match the button text */
  -webkit-mask: var(--icon) center / contain no-repeat;
          mask: var(--icon) center / contain no-repeat;
}
.segmented__btn:hover:not(.is-active) { color: var(--ink); }
.segmented__btn.is-active {
  background: oklch(0.16 0.01 280);
  color: #fff;
}

/* ============================================
   Forecast card
   ============================================ */
.forecast-card {
  grid-column: 1 / -1;
  grid-row: 2;
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 22px 28px 28px;
  position: relative;
  z-index: 2;
  /* Layered like the reference: forecast card is inset on both sides so
     the prompt card sticks out to the left and the segmented to the right. */
  margin: -36px 16px 0 16px;
  /* Locked height so the card never changes size — dashboards, slides, and
     individual slide transitions all share the exact same window dimensions. */
  height: 712px;
  display: flex;
  flex-direction: column;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 600ms cubic-bezier(0.22, 1, 0.36, 1),
              transform 600ms cubic-bezier(0.22, 1, 0.36, 1);
}
.forecast-card.is-in { opacity: 1; transform: translateY(0); }
/* Quick fade-out when switching tabs — overrides the slower default transition. */
.forecast-card.is-leaving {
  transition: opacity 200ms ease-out, transform 200ms ease-out;
  opacity: 0;
}
.forecast-card__title {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.012em;
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.forecast-card__title-text {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.theme-toggle {
  appearance: none;
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  width: 30px;
  height: 30px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-2);
  cursor: pointer;
  transition: background 160ms ease, color 160ms ease, border-color 160ms ease;
}
.theme-toggle:hover { background: var(--card-2); color: var(--ink); }
.theme-toggle:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.theme-toggle__icon { width: 14px; height: 14px; display: block; }
.theme-toggle__icon--moon { display: none; }
.view--dashboards.is-dark .theme-toggle__icon--sun { display: none; }
.view--dashboards.is-dark .theme-toggle__icon--moon { display: block; }
.forecast-card__title-sep,
.forecast-card__title-sub {
  font-weight: 400;
  color: var(--ink-3);
}

/* ============================================
   Horizon row
   ============================================ */
/* ============================================
   Draggable horizon thumb on the chart
   ============================================ */
.chart__plot {
  position: absolute;
  left: 56px;
  right: 14px;
  top: 24px;            /* match the chart's padding-top so the dot tracks the SVG y */
  bottom: 60px;
  z-index: 3;
  touch-action: none;
  cursor: pointer;
}
.chart-thumb {
  --dot-x: 100%;
  --dot-y: 50%;
  position: absolute;
  left: var(--dot-x);
  top: var(--dot-y);
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
  cursor: grab;
  touch-action: none;
  opacity: 0;            /* shown via JS once the line draws to JUN */
}
.chart-thumb:focus-visible { outline: none; }
.chart-thumb.is-dragging { cursor: grabbing; }

.chart-thumb__halo {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(
    circle at center,
    oklch(0.62 0.18 282 / 0.55) 0%,
    oklch(0.62 0.18 282 / 0.30) 35%,
    oklch(0.62 0.18 282 / 0.10) 65%,
    transparent 82%
  );
  animation: haloPulse 3.4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.chart-thumb.is-dragging .chart-thumb__halo {
  animation: none;
  transform: scale(1.15);
  opacity: 1;
}
.chart-thumb__dot {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--brand-strong);
  box-shadow:
    0 0 0 2px #fff,
    0 1px 2px oklch(0.35 0.18 282 / 0.35),
    0 3px 8px oklch(0.35 0.18 282 / 0.25);
}

@keyframes haloPulse {
  0%, 100% { transform: scale(1);    opacity: 0.45; }
  50%      { transform: scale(1.35); opacity: 0.95; }
}

@media (prefers-reduced-motion: reduce) {
  .chart-thumb__halo { animation: none; }
}

/* ============================================
   Chart
   ============================================ */
/* Row: main forecast on the left, secondary confidence chart on the right. */
.chart-row {
  display: grid;
  grid-template-columns: 1.85fr 1fr;
  grid-template-rows: 1fr;
  gap: 18px;
  align-items: stretch;
  flex: 1 1 0;
  min-height: 0;
}
.chart-row > .chart { min-width: 0; min-height: 0; }

.chart {
  position: relative;
  margin-top: 0;
  padding: 32px 14px 14px;                /* extra top room for the TODAY label + 14px gap above the chart */
  border: 1px solid var(--hairline);
  border-radius: var(--r-chip);
  display: grid;
  grid-template-rows: 1fr auto;
  row-gap: 14px;
}

/* Mini chart — mirrors the Model Accuracy chip card's spacing exactly. */
.chart--mini {
  padding: 12px 14px 30px 14px;          /* same as .chip: 12 top, 14 sides; extra bottom for X labels */
  display: flex;
  flex-direction: column;
}
.chart-mini__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  height: 16px;                          /* slim head matching the chip's uppercase label row */
  margin-bottom: 14px;
}
.chart-mini__title {
  white-space: nowrap;                   /* never wrap to a second line — keeps the head height stable */
  overflow: hidden;
  text-overflow: ellipsis;
}
.chart-mini__title {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.chart-mini__legend {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 10.5px;
  color: var(--ink-3);
}
.chart-mini__legend-swatch {
  width: 14px;
  height: 2px;
  background: var(--brand-strong);
  border-radius: 2px;
}
.chart-mini__svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  cursor: crosshair;
  touch-action: none;                     /* mobile: let finger drag across the chart fire pointermove instead of scrolling the page */
}
.chart-mini__line {
  fill: none;
  stroke: var(--brand-strong);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: d 320ms cubic-bezier(0.22, 1, 0.36, 1);
}
.chart-mini__dot {
  fill: transparent;                       /* SVG circle hidden — dots are rendered as HTML overlays so they stay round under preserveAspectRatio="none" */
}
/* Round HTML dots, positioned by percentage of .chart-mini__plot so they
   sit exactly over the SVG data points without inheriting the SVG's
   non-uniform stretch. */
.chart-mini__dots {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  transition-property: opacity;
  transition-duration: 500ms;
  transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}
.chart.is-revealed .chart-mini__dots,
.chart--mini.is-revealed .chart-mini__dots { opacity: 1; }
.chart-mini__dot-html {
  position: absolute;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--brand-strong);
  border: 2px solid var(--card);
  box-sizing: border-box;
  transform: translate(-50%, -50%);
  transition: left 320ms cubic-bezier(0.22, 1, 0.36, 1),
              top 320ms cubic-bezier(0.22, 1, 0.36, 1),
              width 140ms ease, height 140ms ease;
}
.chart-mini__dot-html.is-hover { width: 16px; height: 16px; }
.chart-mini__cursor {
  stroke: var(--ink-3);
  stroke-width: 1;
  stroke-dasharray: 2 3;
}
/* The mini chart's SVG + axis labels share .chart-mini__plot as their
   positioning context, so they all use the SAME coordinate origin (no drift
   between card-top and SVG-top offsets). */
.chart-mini__plot {
  position: relative;
  flex: 1;
  min-height: 0;
}
/* Compound selector (`.chart__y.chart-mini__y`) so we beat the base
   `.chart__y` rule that's defined later in the file. */
.chart__y.chart-mini__y {
  left: 0;
  top: 0;
  height: 100%;                          /* same vertical extent as the SVG it sits over */
  bottom: auto;
  width: auto;
  text-align: left;
  line-height: 1;
}
.chart__y.chart-mini__y span { right: auto; left: 0; }
.chart__x.chart-mini__x {
  position: absolute;                     /* anchor to plot, so bottom: -16px is a real offset */
  left: 0;
  right: 0;
  bottom: -16px;                          /* 14px gap below labels to card edge (with padding-bottom: 30) */
}
.chart-mini__x {
  left: 14px;
  right: 14px;                           /* match the card's 14px right padding so the last X label sits at the same gap */
  bottom: 10px;
}
/* Long-horizon font scaling: when there are too many labels to comfortably
   fit at the default 10.5px, shrink font + tighten letter-spacing so every
   label still fits without thinning. The label widths reduce more than
   linearly, so 11 fits at 9.5px and 12 fits at 9px. */
.chart-mini__x.is-dense span { font-size: 9.5px; letter-spacing: 0.04em; }
.chart-mini__x.is-extra-dense span { font-size: 9px; letter-spacing: 0.02em; }
.chart-mini__tooltip {
  position: absolute;
  pointer-events: none;
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  opacity: 0;
  transform: translate(-50%, -100%) translateY(-10px);
  transition: opacity 140ms ease;
  z-index: 4;
}
.chart-mini__tooltip.is-visible { opacity: 1; }
.chart-mini__tooltip-month {
  display: block;
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 2px;
}
.chart-mini__tooltip-value {
  display: block;
  font-weight: 600;
  color: var(--ink);
}
.chart svg {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 0;
  overflow: visible;
}
/* Y labels overlay the leftmost portion of the chart so the card retains
   equal 14px padding on every side (no separate axis gutter). Height matches
   the SVG height exactly so the labels line up with the gridlines. */
.chart__y {
  position: absolute;
  left: 14px;
  top: 32px;                              /* tracks the chart card's new padding-top so labels align with the gridlines */
  bottom: 42px;
  height: auto;
  width: auto;
  font-size: 11.5px;
  color: var(--ink-mute);
  text-align: left;
  line-height: 1;
  pointer-events: none;
}
.chart__y span {
  position: absolute;
  left: 0;
  transform: translateY(-50%);   /* center each label on its gridline */
  white-space: nowrap;
}
/* Five Y labels: four equally-spaced gridlines (0, 25, 50, 75%) + baseline. */
.chart__y span:nth-child(1) { top: 0;     }   /* yMax       */
.chart__y span:nth-child(2) { top: 25%;   }   /* yMax * .75 */
.chart__y span:nth-child(3) { top: 50%;   }   /* yMax * .5  */
.chart__y span:nth-child(4) { top: 75%;   }   /* yMax * .25 */
.chart__y span:nth-child(5) { top: 100%;  }   /* 0          */
.chart__x {
  position: relative;
  height: 14px;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.1em;
  color: var(--ink-mute);
  text-transform: uppercase;
}
.chart__x span {
  position: absolute;
  transform: translateX(-50%);
  white-space: nowrap;
  top: 0;
}

.grid line {
  stroke: var(--grid);
  stroke-width: 1;
  stroke-dasharray: 2 4;
}
.divider {
  stroke: var(--divider);
  stroke-width: 1;
  stroke-dasharray: 2 3;                  /* dotted, mirroring the confidence chart's cursor line */
  opacity: 0;
  /* Listed explicitly so the longer fade survives the .view--dashboards *
     transition-property override defined later in this file. */
  transition-property: opacity, stroke;
  transition-duration: 700ms;
  transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}
.chart.is-revealed .divider { opacity: 0.8; }
/* TODAY label that tracks the SVG divider's x position via --today-frac
   (set from JS as a fraction 0..1 of SVG_W). Sits in the chart card's 14px
   top padding band, centered horizontally over the divider line. */
.chart__today {
  position: absolute;
  top: 10px;                              /* sits in the card's new 32px top padding, with breathing room above and 14px gap to the chart below */
  left: calc(14px + (100% - 28px) * var(--today-frac, 0.5));
  transform: translateX(-50%);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.18em;
  color: var(--ink-3);
  text-transform: uppercase;
  pointer-events: none;
  opacity: 0;
  /* Higher specificity than the .view--dashboards * rule so the longer fade
     duration sticks. Listed properties cover color/opacity. */
  transition-property: opacity, color;
  transition-duration: 700ms;
  transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}
.chart.is-revealed .chart__today { opacity: 1; }
.line {
  fill: none;
  stroke: var(--brand-strong);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
  /* Smooth path-to-path tween when slider values change. */
  transition: d 320ms cubic-bezier(0.22, 1, 0.36, 1);
}
.chart-area {
  fill: url(#chartAreaGrad);
  transition: d 320ms cubic-bezier(0.22, 1, 0.36, 1);
}
/* While the user is actively dragging a slider, disable the `d` transition
   on all chart paths so the line tracks the cursor frame-by-frame instead of
   easing toward a moving target (which reads as stutter). */
.is-slider-active .line,
.is-slider-active .chart-area,
.is-slider-active .chart-mini__line {
  transition: none !important;
}
/* Main-chart hover cursor + dot + tooltip — same visual language as the
   confidence chart but scaled to the main chart card. Note: NO
   `touch-action: none` here — on mobile we want the user to be able to
   touch / drag over the dashboards chart without the page hijacking the
   scroll. Hover still works on desktop via pointermove from a mouse. */
.chart-cursor {
  stroke: var(--ink-3);
  stroke-width: 1;
  stroke-dasharray: 2 3;
}
.chart__hover-dot {
  position: absolute;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--brand-strong);
  border: 2px solid var(--card);
  box-sizing: border-box;
  transform: translate(-50%, -50%);
  pointer-events: none;
  opacity: 0;
  transition: opacity 140ms ease;
  z-index: 4;
}
.chart__hover-dot.is-visible { opacity: 1; }
.chart__tooltip {
  position: absolute;
  pointer-events: none;
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  opacity: 0;
  transform: translate(-50%, -100%) translateY(-14px);
  transition: opacity 140ms ease;
  z-index: 4;
  box-shadow: 0 6px 16px rgba(0,0,0,0.08);
}
.chart__tooltip.is-visible { opacity: 1; }
.chart__tooltip-month {
  display: block;
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 2px;
}
.chart__tooltip-value {
  display: block;
  font-weight: 600;
  color: var(--ink);
}
.line--dashed {
  stroke-dasharray: 5 5;
}

/* ============================================
   Chips
   ============================================ */
.chips {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18px;
  margin-top: 18px;
  margin-bottom: 18px;
}

/* Forecast controls — two slider inputs that drive the chart. */
.forecast-controls {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
  margin-top: 14px;
}
.forecast-input {
  border: 1px solid var(--hairline);
  border-radius: var(--r-chip);
  padding: 10px 16px 4px;                /* slimmed top/bottom to absorb the slider's new 44px height while keeping the card's overall height stable */
  background: transparent;
}
.forecast-input__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 0;
}
.forecast-input__label {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.forecast-input__value {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
/* Reset native range + paint a slim track + matching thumb.
   The track gets a subtle purple bloom centered on the thumb, and the thumb
   itself has a purple halo glow — JS keeps `--thumb-pos` in sync with the
   slider value so the bloom follows the thumb. */
.forecast-input__track-wrap {
  position: relative;
  --thumb-pos: 50%;
}
/* Overlay halo that visually pulses around the slider thumb. Sits on top
   of the input, positioned at --thumb-pos via JS — bypasses the rendering
   quirks of animating ::-webkit-slider-thumb. */
.forecast-input__halo {
  position: absolute;
  top: 50%;
  left: var(--thumb-pos);
  width: 16px;
  height: 16px;
  margin-left: -8px;                      /* centered on the slider thumb */
  margin-top: -8px;
  border-radius: 50%;
  background: var(--brand-strong);        /* this is THE visible dot — native thumb is invisible */
  pointer-events: none;
  z-index: 2;                             /* in front of the slider track so the line doesn't cross the dot */
  animation: forecastThumbPulse 2.4s ease-in-out infinite;
}
@keyframes forecastThumbPulse {
  0%, 100% {
    box-shadow:
      0 0 0 4px  oklch(0.62 0.18 282 / 0.40),
      0 0 18px 4px oklch(0.62 0.18 282 / 0.55);
  }
  50% {
    box-shadow:
      0 0 0 11px oklch(0.62 0.18 282 / 0.22),
      0 0 32px 10px oklch(0.62 0.18 282 / 0.32);
  }
}
@media (prefers-reduced-motion: reduce) {
  .forecast-input__halo { animation: none; box-shadow: 0 0 18px 4px oklch(0.62 0.18 282 / 0.45); }
}
/* Dark mode: white glow, lower opacity than the purple version — white on a
   dark surface reads much brighter at the same alpha, so the pulse is dialled
   back to roughly half intensity. */
@keyframes forecastThumbPulseDark {
  0%, 100% {
    box-shadow:
      0 0 0 4px  oklch(1 0 0 / 0.18),
      0 0 18px 4px oklch(1 0 0 / 0.22);
  }
  50% {
    box-shadow:
      0 0 0 11px oklch(1 0 0 / 0.10),
      0 0 32px 10px oklch(1 0 0 / 0.14);
  }
}
.view--dashboards.is-dark .forecast-input__halo {
  animation: forecastThumbPulseDark 2.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .view--dashboards.is-dark .forecast-input__halo { animation: none; box-shadow: 0 0 18px 4px oklch(1 0 0 / 0.18); }
}
.forecast-input__range {
  --thumb-pos: 50%;
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 44px;                          /* generous tap zone — track is still visually 4px */
  background: transparent;
  cursor: pointer;
  position: relative;
  z-index: 1;                            /* keep the real slider above the halo so the user can drag it */
  touch-action: none;                    /* mobile: prevent the page from scrolling while the user drags the thumb horizontally */
  display: block;
  /* Let the wrapper grow to the input's full 44px height (no negative-margin
     collapse). This keeps the halo's `top: 50%` aligned with the track on
     every browser — including iOS Safari, which draws the track at the
     visible center of the input regardless of layout-box collapsing. */
}
.forecast-input__range:focus { outline: none; }
.forecast-input__range::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 999px;
  background:
    radial-gradient(
      ellipse 130px 12px at var(--thumb-pos) center,
      oklch(0.62 0.18 282 / 0.55) 0%,
      oklch(0.62 0.18 282 / 0.20) 50%,
      transparent 100%
    ),
    var(--hairline);
}
.forecast-input__range::-moz-range-track {
  height: 4px;
  border-radius: 999px;
  background:
    radial-gradient(
      ellipse 130px 12px at var(--thumb-pos) center,
      oklch(0.62 0.18 282 / 0.55) 0%,
      oklch(0.62 0.18 282 / 0.20) 50%,
      transparent 100%
    ),
    var(--hairline);
}
/* Native thumbs are invisible — the .forecast-input__halo overlay renders the
   visible dot + glow. Native thumbs stay interactive so dragging still works. */
.forecast-input__range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  /* Thumb width stays at 16px so the halo (positioned 0-100% across the
     wrapper via JS) stays visually aligned with the actual thumb. The 44px
     slider HEIGHT provides the touch target — browsers snap the slider to
     the tap position anywhere along the input's hit area. */
  width: 16px;
  height: 16px;
  margin-top: -6px;                       /* centers the 16px thumb on the 4px track */
  border-radius: 50%;
  background: transparent;
  border: 0;
  box-shadow: none;
  cursor: grab;
}
.forecast-input__range:active::-webkit-slider-thumb { cursor: grabbing; }
.forecast-input__range::-moz-range-thumb {
  width: 16px;                            /* same logic as webkit — halo math depends on a 16px thumb */
  height: 16px;
  border-radius: 50%;
  background: transparent;
  border: 0;
  box-shadow: none;
  cursor: grab;
}
@keyframes sliderThumbPulse {
  0%, 100% {
    box-shadow:
      0 0 0 2px #fff,
      0 0 0 8px oklch(0.62 0.18 282 / 0.35),
      0 0 20px 6px oklch(0.62 0.18 282 / 0.65),
      0 0 40px 14px oklch(0.62 0.18 282 / 0.30);
  }
  50% {
    box-shadow:
      0 0 0 2px #fff,
      0 0 0 12px oklch(0.62 0.18 282 / 0.50),
      0 0 32px 10px oklch(0.62 0.18 282 / 0.95),
      0 0 60px 20px oklch(0.62 0.18 282 / 0.50);
  }
}
@media (prefers-reduced-motion: reduce) {
  .forecast-input__range::-webkit-slider-thumb,
  .forecast-input__range::-moz-range-thumb {
    animation: none;
    box-shadow:
      0 0 0 2px #fff,
      0 0 0 6px oklch(0.62 0.18 282 / 0.22),
      0 0 18px 6px oklch(0.62 0.18 282 / 0.50);
  }
}
.chip {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 14px 14px;
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: var(--r-chip);
}
.chip__label {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.chip__value {
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.chip__sub {
  font-size: 12px;
  color: var(--ink-2);
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.chip__sub--positive { color: var(--up); font-weight: 600; }
.chip__sub--positive svg { width: 8px; height: 8px; }
.chip__sub-dim { color: var(--ink-2); font-weight: 400; }

/* ============================================
   View switching
   ============================================ */
.view { display: none; }
.view.is-active { display: block; }
/* Dashboards view uses a flex column so .chart-row can claim the remaining
   vertical space inside the locked-height forecast card. */
.view--dashboards.is-active { display: flex; flex-direction: column; }

/* Dark theme overrides — toggled by the .theme-toggle button. Mirrors the
   slides view's dark palette so the chart card reads on a dark surface. */
.view--dashboards.is-dark {
  --card:         oklch(0.20 0.008 280);
  --card-2:       oklch(0.23 0.008 280);
  --hairline:     oklch(0.36 0.008 280);
  --hairline-2:   oklch(0.32 0.006 280);
  /* All text / numbers white in dark mode (per spec). */
  --ink:          #ffffff;
  --ink-2:        #ffffff;
  --ink-3:        #ffffff;
  --ink-mute:     #ffffff;
  --grid:         oklch(0.36 0.006 280);
  --divider:      oklch(0.62 0.008 280);
  /* All brand purple swaps to white so chart lines, dots, area gradient,
     and slider track read in monochrome on the dark surface. */
  --brand:         #ffffff;
  --brand-strong:  #ffffff;
  --brand-soft:    oklch(1 0 0 / 0.18);
  --brand-halo:    oklch(1 0 0 / 0.28);
  background: var(--card);
  color: var(--ink);
}
/* Slider track gradient — inline oklch purple in the base rule. Re-declared
   here with white so dark mode matches the rest of the chart. */
.view--dashboards.is-dark .forecast-input__range::-webkit-slider-runnable-track {
  background:
    radial-gradient(
      ellipse 130px 12px at var(--thumb-pos) center,
      oklch(1 0 0 / 0.55) 0%,
      oklch(1 0 0 / 0.20) 50%,
      transparent 100%
    ),
    var(--hairline);
}
.view--dashboards.is-dark .forecast-input__range::-moz-range-track {
  background:
    radial-gradient(
      ellipse 130px 12px at var(--thumb-pos) center,
      oklch(1 0 0 / 0.55) 0%,
      oklch(1 0 0 / 0.20) 50%,
      transparent 100%
    ),
    var(--hairline);
}
/* Chart-area gradient: inline stops in the SVG defs use hardcoded brand
   purple (#5B5BD6). Override per-stop in dark mode to white. */
.view--dashboards.is-dark #chartAreaGrad stop { stop-color: #ffffff; }
/* Smooth cross-fade between light and dark themes. Applied to the dashboards
   view and everything inside; lets all background/border/color/fill/stroke/
   opacity changes ease over ~360ms instead of snapping. opacity is included
   so things like the TODAY label and divider can fade in (their .is-revealed
   transition would otherwise be clobbered by this rule's source order). */
.view--dashboards,
.view--dashboards * {
  transition-property: background-color, border-color, color, fill, stroke, box-shadow, opacity;
  transition-duration: 360ms;
  transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ============================================
   Slide deck — dark theme scoped to .view--slides
   ============================================ */
.view--slides {
  /* Surfaces */
  --card:         oklch(0.20 0.008 280);
  --bg-opacity:   0.6;          /* default: dimmed on non-cover slides */
  position: relative;
  overflow: hidden;
}
/* Background texture for the slide deck — full strength on the cover slide,
   knocked back on the rest via the --bg-opacity variable. */
.view--slides::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url('slides-bg.png');
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  opacity: var(--bg-opacity, 0.6);
  border-radius: inherit;
  pointer-events: none;
  z-index: 0;
  transition: opacity 1100ms cubic-bezier(0.22, 1, 0.36, 1);
}
.view--slides > * { position: relative; z-index: 1; }
.view--slides {
  --card-2:       oklch(0.23 0.008 280);
  --hairline:     oklch(0.36 0.008 280);
  --hairline-2:   oklch(0.32 0.006 280);

  /* Text */
  --ink:          oklch(0.97 0.005 280);
  --ink-2:        oklch(0.74 0.008 280);
  --ink-3:        oklch(0.58 0.006 280);
  --ink-mute:     oklch(0.50 0.005 280);

  /* Chart strokes / dividers */
  --grid:         oklch(0.36 0.006 280);
  --divider:      oklch(0.48 0.008 280);

  /* Slide-deck shadow — tuned to read on both dark and light surfaces.
     Lower alphas and a tighter spread (16px → previously 56px) so the
     shadow doesn't bleed visibly across a coloured Framer canvas. */
  box-shadow:
    0 1px 2px oklch(0 0 0 / 0.12),
    0 4px 10px oklch(0 0 0 / 0.10),
    0 12px 28px oklch(0 0 0 / 0.12);
}

/* Roboto on every heading inside the deck for a clear visual fork from the dashboards. */
.view--slides .slide-title,
.view--slides .slide-stat__num,
.view--slides .kpi-card__num,
.view--slides .kpi-strip__num,
.view--slides .support-stat__num,
.view--slides .slide-contents__list .name {
  font-family: "Britti Sans", "Roboto", var(--font);
  font-weight: 600;                       /* Britti Sans Semibold */
}

/* Solid dark panel for callouts on slides. */
.view--slides .callout {
  background: transparent;
  border: 1px solid var(--hairline);
  color: var(--ink-2);
}
.view--slides .callout strong { color: var(--ink); }
.view--slides .callout--brand  { border-color: oklch(0.48 0.10 282);  background: oklch(0.23 0.04 282 / 0.45); }
.view--slides .callout--accent { border-color: oklch(0.55 0.13 30);   background: oklch(0.26 0.06 30 / 0.45); }
.view--slides .callout--good   { border-color: oklch(0.52 0.13 160);  background: oklch(0.24 0.05 160 / 0.45); }
.slide[data-slide-name="By Country"] .callout--good,
.slide[data-slide-name="Top Partners"] .callout--good,
.slide[data-slide-name="Top Products"] .callout--good { color: var(--ink); }
/* Support slide — callouts match the stat-card treatment exactly: same padding,
   same hairline border, same glass fill. Colored variants get reset here. */
.slide[data-slide-name="Support"] .callouts {
  grid-template-columns: 1fr;   /* stack on top of each other */
  gap: 12px;
}
.slide[data-slide-name="Support"] .callout,
.slide[data-slide-name="Support"] .callout--good,
.slide[data-slide-name="Support"] .callout--brand,
.slide[data-slide-name="Support"] .callout--accent {
  padding: 12px 14px 14px;
  border: 1px solid var(--hairline);
  background: rgba(0, 0, 0, 0.35);
  color: var(--ink-2);
}
/* Neutralize the colored ↗ arrow so the callouts blend with the neutral stat cards. */
.slide[data-slide-name="Support"] .callout--good::before,
.slide[data-slide-name="Support"] .callout--brand::before,
.slide[data-slide-name="Support"] .callout--accent::before {
  color: var(--ink-3);
}

/* Margin pill — invert from light-green to a deeper green chip on dark bg. */
.view--slides .margin-pill {
  background: oklch(0.30 0.06 160);
  color: oklch(0.86 0.10 160);
}

/* Period toggle: keep brand purple for the active state but make the rest read on dark. */
.view--slides .period-btn {
  background: transparent;
  border-color: oklch(0.40 0.01 280);
  color: var(--ink-2);
}
.view--slides .period-btn:hover {
  color: var(--ink);
  border-color: #fff;
}
.view--slides .period-btn.is-active:hover { border-color: #fff; }
.view--slides .period-btn.is-active {
  background: #fff;
  color: #000;
  border-color: #fff;
}

/* Slide arrow buttons: dark surface with white icon, halo glow unchanged. */
.view--slides .slide-arrow { color: var(--ink); }

/* The trend chart's area gradient + line look slightly brighter to read on dark. */
.view--slides .trend-line { stroke: oklch(0.72 0.18 282); }
.view--slides .trend-line--mute { stroke: oklch(0.65 0.14 160); }

/* ============================================
   Slide deck (slides view)
   ============================================ */
.slide-deck {
  position: relative;       /* anchor for the floating top-right arrows */
  display: flex;
  flex-direction: column;
  height: 100%;             /* fill the locked-height card */
}

.slide-deck__topnav {
  position: absolute;
  top: 0;
  right: 0;
  display: flex;
  gap: 8px;
  z-index: 4;
}

.slide-deck__topbar { display: none; }

.slide-deck__viewport {
  position: relative;
  flex: 1 1 auto;            /* fills whatever space is left */
  overflow: hidden;          /* clip anything that doesn't fit instead of growing */
  min-height: 0;
}

.slide {
  display: flex;
  flex-direction: column;
  position: absolute;
  inset: 0;
  overflow: hidden;
}
.slide > .slide-sub { flex: 0 0 auto; }
.slide > .slide-title { flex: 0 0 auto; }
.slide > .callouts  { flex: 0 0 auto; }
.slide[hidden] { display: none; }

.slide-title {
  margin: 0 0 8px;
  font-size: 32px;
  font-weight: 700;
  letter-spacing: -0.022em;
  color: var(--ink);
  line-height: 1.05;
}
.slide-title--xl {
  font-size: 64px;
  letter-spacing: -0.035em;
  line-height: 0.95;
  display: flex;
  flex-direction: column;
}
.slide-title--xl .is-accent { color: var(--ink); }

.slide-sub,
.slide-lede {
  margin: 0;
  color: var(--ink-2);
  letter-spacing: -0.012em;
}
.slide-sub { font-size: 18px; margin-bottom: 16px; line-height: 1.4; }
.slide-lede { font-size: 18px; max-width: 38ch; margin-bottom: 22px; line-height: 1.45; }

/* ---- Slide 1: cover ---- */
.slide--cover {
  flex: 1;
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 40px;
  min-height: 0;
}
.slide--cover__main {
  display: flex;
  flex-direction: column;
  padding-top: 4px;
  min-height: 0;
}
.slide--cover__main .slide-stats {
  margin-top: auto;          /* push stats to the bottom; title + lede stay tight at top */
}
/* At-a-glance stats moved onto the cover, anchored to the bottom-left. */
.cover-stats {
  margin-top: 32px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 32px;
  row-gap: 24px;
  text-align: left;
}
.cover-stat { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.cover-stat__label {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
  line-height: 1.2;
}
.cover-stat__num {
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.025em;
  color: var(--ink);
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
.cover-stat__sub {
  font-size: 12px;
  color: var(--ink-2);
  line-height: 1.3;
}
.slide-stats {
  display: flex;
  padding-top: 16px;
  margin-top: 8px;
}
.slide-stat {
  flex: 1;
  display: flex;
  flex-direction: column;
}
.slide-stat__num { line-height: 1; }
.slide-stat__label { line-height: 1; margin-top: 4px; }
.slide-stat__num {
  font-size: 28px; font-weight: 700; letter-spacing: -0.025em;
  color: var(--ink); line-height: 1;
}
.slide-stat__label {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-3);
}
.slide--cover__contents {
  padding-top: 6px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 0;
}
.slide-contents__title {
  margin: 0 0 4px;
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-3);
}
.slide-contents__list {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column;
}
.slide-contents__list li {
  display: grid;
  grid-template-columns: 32px 1fr;
  align-items: center;
  column-gap: 14px;
  row-gap: 4px;
  padding: 16px 0;           /* breathing room between the dividing lines */
  border-top: 1px solid var(--hairline);
  font-size: 12.5px;
  line-height: 1.2;
}
.slide-contents__list li:first-child { border-top: 0; }
/* Compact variant — no subtitles. Stretches to fill the column height with
   each item taking an equal share, evenly spaced. */
.slide-contents__list--compact { display: none; }
.slide-contents__list .num {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  grid-row: 1;
  grid-column: 1;
  align-self: start;
  padding-top: 4px;
}
.slide-contents__list .name {
  color: var(--ink);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -0.012em;
  line-height: 1.3;
  grid-row: 1;
  grid-column: 2;
}
.slide-contents__list .desc {
  color: var(--ink-2);
  grid-row: 2;
  grid-column: 2;
  font-size: 18px;
  letter-spacing: -0.012em;
  line-height: 1.4;
}

/* ---- Slide 2: KPIs ---- */
.kpi-grid {
  flex: 1;
  display: grid;
  grid-template-columns: auto auto;
  grid-template-rows: auto auto;
  align-content: end;             /* push the two rows toward the bottom of the slide */
  justify-content: end;           /* push the two columns toward the right of the slide */
  gap: 60px 60px;
  margin-top: 8px;
  min-height: 0;
  padding-bottom: 24px;           /* keep a bit of breathing room above the period bar */
}
.kpi-card {
  display: flex;
  flex-direction: column;
  padding: 4px 6px;
  background: transparent;
}
.kpi-card__label {
  margin-top: auto;                /* push the whole stack to the bottom */
  align-self: flex-end;
  text-align: right;
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink);
}
.kpi-card__num {
  margin-top: 8px;
  align-self: flex-end;
  text-align: right;
  font-size: 40px; font-weight: 700; letter-spacing: -0.026em;
  color: var(--ink); font-variant-numeric: tabular-nums;
  line-height: 1;
}
.kpi-card__sub {
  align-self: flex-end;
  text-align: right;
  margin-top: 6px;
  font-size: 18px; color: var(--ink-2);
  letter-spacing: -0.012em;
  line-height: 1.4;
  white-space: nowrap;
}


/* ---- Slide 3: Revenue Trend ---- */
.kpi-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;             /* match dashboards chip gap */
  margin-top: 8px;
  flex: 0 0 auto;
}
.kpi-strip__cell {
  display: flex; flex-direction: column; gap: 6px;
  padding: 12px 14px 14px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-chip);
  background: transparent;
}
.kpi-strip__label {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-3);
}
.kpi-strip__num {
  font-size: 24px; font-weight: 700; letter-spacing: -0.02em;
  color: var(--ink); font-variant-numeric: tabular-nums; line-height: 1.1;
}
.kpi-strip__sub { font-size: 12px; color: var(--ink-2); }

.trend-legend {
  display: flex; gap: 18px; margin: 0;
  font-size: 12px; color: var(--ink-2);
  flex: 0 0 auto;
}
.trend-legend[hidden] { display: none; }
.trend-legend__item { display: inline-flex; align-items: center; gap: 6px; }
.dot {
  width: 10px; height: 2px; border-radius: 999px;
  display: inline-block;
  vertical-align: middle;
}
/* Optical centering with cap-height of adjacent uppercase text only —
   in mixed-case contexts (like trend-legend) the bare middle alignment is right. */
.rank-table thead .dot { margin-bottom: 4px; }
.dot--brand { background: var(--brand); }
.dot--mute { background: var(--ink-mute); }
.view--slides .dot--mute { background: oklch(0.65 0.14 160); }
.dot--accent { background: oklch(0.65 0.18 30); }

.trend-chart {
  position: relative;
  padding: 24px 14px 60px 56px;      /* match dashboards .chart exactly */
  border: 1px solid var(--hairline);
  border-radius: var(--r-chip);
  flex: 1;
  min-height: 0;
  margin-top: 14px;                  /* equal breathing room above and below the chart */
}
.trend-chart svg {
  display: block; width: 100%; height: 100%; overflow: visible;
  touch-action: none;                              /* mobile: tap + finger drag fire pointer events instead of scrolling */
}
.trend-grid line {
  stroke: var(--grid);
  stroke-width: 1;
  stroke-dasharray: 2 4;
  vector-effect: non-scaling-stroke;   /* keep grid hairline-thin regardless of SVG stretch */
}
.trend-area { fill: url(#trendAreaGrad); }
.trend-line {
  fill: none; stroke: var(--brand-strong); stroke-width: 2;
  stroke-linejoin: round; stroke-linecap: round;
}
.trend-line--mute { stroke: var(--ink-mute); stroke-width: 1.2; }

/* Revenue Trend reveal: wipe the data paths (area + both lines) in from left → right
   when the slide becomes active. Grid + axis labels stay visible the whole time. */
.slide[data-slide-name="Revenue Trend"].is-active .trend-data {
  animation: trendDataWipe 1100ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes trendDataWipe {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}

/* Hover indicators on the trend chart */
.trend-hover-line {
  stroke: oklch(0.62 0.18 282);
  stroke-width: 1.5;
  pointer-events: none;
  transition: opacity 120ms ease;
}
.trend-chart__overlay {
  position: absolute;
  left: 56px;
  right: 14px;
  top: 24px;
  bottom: 60px;
  pointer-events: none;
  z-index: 4;
}
.trend-hover-dot {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -50%);
  /* No transitions — the dot must appear at its committed position instantly,
     otherwise the eye catches the fade happening before mousemove finishes. */
  z-index: 5;
}
.trend-hover-dot--rev {
  width: 12px;
  height: 12px;
  background: oklch(0.62 0.18 282);
  box-shadow: 0 0 0 3px oklch(0.62 0.18 282 / 0.25);
}
.trend-hover-dot--profit {
  width: 10px;
  height: 10px;
  background: oklch(0.65 0.14 160);
  box-shadow: 0 0 0 3px oklch(0.65 0.14 160 / 0.25);
}

.trend-tooltip {
  position: absolute;
  background: rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(14px) saturate(120%);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  padding: 10px 14px 12px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 140ms ease;
  z-index: 10;
  min-width: 170px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
}
.trend-tooltip.is-active { opacity: 1; }
.trend-tooltip__date {
  color: var(--ink-3);
  font-size: 12px;
  margin-bottom: 6px;
}
.trend-tooltip__row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  line-height: 1.4;
}
.trend-tooltip__row strong { color: var(--ink); font-weight: 700; }
.trend-tooltip__row > span:last-child { color: var(--ink-3); }
.trend-tooltip__dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  display: inline-block;
}
.trend-tooltip__dot--rev    { background: oklch(0.62 0.18 282); }
.trend-tooltip__dot--profit { background: oklch(0.65 0.14 160); }
.trend-y {
  position: absolute; left: 0; top: 24px; bottom: 60px;
  width: 56px;
  font-size: 11.5px; color: var(--ink-mute);
  text-align: right;
}
.view--slides .trend-y { color: var(--ink); }
.trend-y span {
  position: absolute;
  right: 8px;
  transform: translateY(-50%);
  white-space: nowrap;
}
.trend-y span:nth-child(1) { top: 0;    }
.trend-y span:nth-child(2) { top: 25%;  }
.trend-y span:nth-child(3) { top: 50%;  }
.trend-y span:nth-child(4) { top: 75%;  }
.trend-y span:nth-child(5) { top: 100%; }

/* ---- Top Partners: vertical bar chart inside a trend-chart shell ---- */
/* Partners chart has no Y-axis labels — override the trend-chart's asymmetric padding
   so bars/labels sit with equal breathing room on all four sides. */
.partners-chart {
  padding: 24px 28px 48px 28px;
  margin-top: 0;   /* match .country-map (which has no top margin) so heights align */
  background: transparent;
}
.partners-overlay {
  position: absolute;
  left: 28px;
  right: 28px;
  top: 24px;
  bottom: 48px;
  display: flex;
  align-items: flex-end;
  gap: 28px;
}
.partner-col {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  height: 100%;
}
.partner-col__value {
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.012em;
}
.partner-col__bar {
  width: 100%;
  max-width: 90px;
  height: var(--w, 50%);
  /* Default: white gradient (matching default map pins / neutral indicators) */
  background: linear-gradient(180deg,
    oklch(0.97 0.005 280) 0%,
    oklch(0.78 0.005 280) 100%);
  border-radius: 10px 10px 0 0;
  transition: height 800ms cubic-bezier(0.22, 1, 0.36, 1);
}
/* The #1 partner (first column) reads as the leader — same green as the US "top market" pin/chip. */
.partner-col:first-child .partner-col__bar {
  background: linear-gradient(180deg,
    oklch(0.78 0.16 160) 0%,
    oklch(0.52 0.14 160) 100%);
}

/* Shoot-up reveal when the Top Partners slide becomes active.
   Uses transform (scaleY) so it doesn't conflict with the height transition used
   during period changes. transform-origin: bottom makes them grow upward. */
.partners-overlay .partner-col__bar {
  transform-origin: bottom center;
}
.slide[data-slide-name="Top Partners"].is-active .partner-col__bar {
  animation: barRise 500ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.slide[data-slide-name="Top Partners"].is-active .partner-col:nth-child(1) .partner-col__bar { animation-delay: 60ms; }
.slide[data-slide-name="Top Partners"].is-active .partner-col:nth-child(2) .partner-col__bar { animation-delay: 120ms; }
.slide[data-slide-name="Top Partners"].is-active .partner-col:nth-child(3) .partner-col__bar { animation-delay: 180ms; }
.slide[data-slide-name="Top Partners"].is-active .partner-col:nth-child(4) .partner-col__bar { animation-delay: 240ms; }
@keyframes barRise {
  from { transform: scaleY(0); }
  to   { transform: scaleY(1); }
}

/* Value labels pop in right after each bar settles. */
.slide[data-slide-name="Top Partners"].is-active .partner-col__value {
  animation: barValuePop 220ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.slide[data-slide-name="Top Partners"].is-active .partner-col:nth-child(1) .partner-col__value { animation-delay: 560ms; }
.slide[data-slide-name="Top Partners"].is-active .partner-col:nth-child(2) .partner-col__value { animation-delay: 620ms; }
.slide[data-slide-name="Top Partners"].is-active .partner-col:nth-child(3) .partner-col__value { animation-delay: 680ms; }
.slide[data-slide-name="Top Partners"].is-active .partner-col:nth-child(4) .partner-col__value { animation-delay: 740ms; }
@keyframes barValuePop {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.partners-x {
  position: absolute;
  left: 28px;
  right: 28px;
  bottom: 24px;
  height: 14px;
  display: flex;
  gap: 28px;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
}
.partners-x span {
  flex: 1;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---- Revenue by Country: world map with pulsing pins ---- */
.country-map {
  position: relative;
  flex: 1;
  border: 1px solid var(--hairline);
  border-radius: var(--r-chip);
  overflow: hidden;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Glass background to match support stat cards / map chips */
  background: rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(14px) saturate(120%);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
}
.country-map__inner {
  /* Match the SVG's exact aspect ratio so pin %s align with country positions in the map.
     No max-height — it would clamp the inner and break aspect (causing pins to drift)
     when the parent's height/width ratio differs from the map. The parent has overflow:
     hidden so any overflow gets clipped, but pin %s stay accurate. */
  position: relative;
  aspect-ratio: 1011 / 666;
  width: 100%;
  max-width: 100%;
  /* translateY lifts the whole map + pins as a unit (slight optical balance). */
  transform: translateY(-4%) scale(1.18);
  transform-origin: 50% 50%;
}
.country-map__base {
  width: 100%;
  height: 100%;
  background-image: url("world-optimized.svg");
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  opacity: 0.15;
  /* Block long-press / right-click "save image" menus and drag-out. */
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-user-drag: none;
}
.country-map__pins {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.country-pin {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: 0;
  height: 0;
  transform: scale(0.847); /* counter-scale 1/1.18 so dot+label stay normal size */
  /* Hidden by default; the slide adds .is-pins-revealed on first visit to
     fire the staggered fade-in, then pins stay visible. Using visibility +
     animation-fill-mode so we never leave the pin at opacity < 1, which
     would otherwise break the label's backdrop-filter blur. */
  visibility: hidden;
}
.slide[data-slide-name="By Country"].is-pins-revealed .country-pin {
  animation: pinAppear 280ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.slide[data-slide-name="By Country"].is-pins-revealed .country-pin:nth-child(1) { animation-delay: 0ms;   }
.slide[data-slide-name="By Country"].is-pins-revealed .country-pin:nth-child(2) { animation-delay: 80ms;  }
.slide[data-slide-name="By Country"].is-pins-revealed .country-pin:nth-child(3) { animation-delay: 160ms; }
.slide[data-slide-name="By Country"].is-pins-revealed .country-pin:nth-child(4) { animation-delay: 240ms; }
.slide[data-slide-name="By Country"].is-pins-revealed .country-pin:nth-child(5) { animation-delay: 320ms; }
.slide[data-slide-name="By Country"].is-pins-revealed .country-pin:nth-child(6) { animation-delay: 400ms; }
.slide[data-slide-name="By Country"].is-pins-revealed .country-pin:nth-child(7) { animation-delay: 480ms; }
.slide[data-slide-name="By Country"].is-pins-revealed .country-pin:nth-child(8) { animation-delay: 560ms; }
@keyframes pinAppear {
  from { visibility: visible; opacity: 0; transform: scale(0.847) translateY(4px); }
  to   { visibility: visible; opacity: 1; transform: scale(0.847) translateY(0); }
}
.country-pin__dot {
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-50%, -50%);
}
.country-pin__label {
  position: absolute;
  /* default: label below the dot */
  top: 14px;
  left: 0;
  transform: translateX(-50%);
}
.country-pin--up .country-pin__label    { top: auto; bottom: 14px; left: 0; transform: translateX(-50%); }
.country-pin--down .country-pin__label  { top: 14px; left: 0; transform: translateX(-50%); }
.country-pin--left .country-pin__label  { top: 0; left: auto; right: 14px; transform: translateY(-50%); }
.country-pin--right .country-pin__label { top: 0; left: 14px; transform: translateY(-50%); }
.country-pin__dot {
  /* Default: white. Override per pin via .country-pin--good etc. */
  --dot-l: 0.97;
  --dot-c: 0.005;
  --dot-h: 280;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: oklch(var(--dot-l) var(--dot-c) var(--dot-h));
  animation: countryPulse 2.4s ease-in-out infinite;
}
.country-pin--good .country-pin__dot {
  /* Green — signals the top market */
  --dot-l: 0.68;
  --dot-c: 0.16;
  --dot-h: 160;
}
@keyframes countryPulse {
  0%, 100% {
    box-shadow:
      0 0 0 4px  oklch(var(--dot-l) var(--dot-c) var(--dot-h) / 0.28),
      0 0 14px 2px oklch(var(--dot-l) var(--dot-c) var(--dot-h) / 0.35);
  }
  50% {
    box-shadow:
      0 0 0 10px oklch(var(--dot-l) var(--dot-c) var(--dot-h) / 0.16),
      0 0 24px 6px oklch(var(--dot-l) var(--dot-c) var(--dot-h) / 0.22);
  }
}
.country-pin__label {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  /* Same glass treatment as the trend-tooltip */
  background: rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(14px) saturate(120%);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  border: 1px solid var(--hairline);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
  border-radius: 12px;
  padding: 6px 12px;
  font-size: 16px;
  line-height: 1.2;
  white-space: nowrap;
  color: var(--ink-3);
  margin-top: 4px;
}
.country-pin__label strong {
  font-weight: 700;
  color: var(--ink);
  font-size: 16px;
  letter-spacing: 0.04em;
}
.country-pin__label span {
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  font-weight: 600;
}
.trend-x {
  position: absolute; left: 56px; right: 14px; bottom: 16px;
  display: flex; justify-content: space-between;
  font-size: 10.5px; font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
}
.view--slides .trend-x { color: var(--ink); }

/* ---- Callouts ---- */
.callouts {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin: 8px 0 14px;
}
/* Generous breathing on By Country + Top Partners so the title/subtext have
   room to breathe (matching the Support slide rhythm). The map and bars then
   take whatever vertical space is left — explicit flex sizing so they don't
   leave any gap below. */
.slide[data-slide-name="By Country"] .slide-sub,
.slide[data-slide-name="Top Partners"] .slide-sub { margin-bottom: 8px; }
.slide[data-slide-name="By Country"] .callouts,
.slide[data-slide-name="Top Partners"] .callouts { margin: 16px 0 20px; }
.slide[data-slide-name="By Country"] .country-map,
.slide[data-slide-name="Top Partners"] .partners-chart {
  flex: 1 1 0;
  min-height: 0;
  margin-bottom: 0;
}
.callout {
  padding: 10px 14px;
  border-radius: var(--r-chip);
  border: 1px solid var(--hairline);
  font-size: 12.5px;
  color: var(--ink-2);
  line-height: 1.45;
}
.callout strong { color: var(--ink); font-weight: 600; }
.callout::before {
  content: "↗ ";
  color: var(--ink-mute);
  font-weight: 600;
}
.callout--brand { border-color: oklch(0.85 0.06 282); background: oklch(0.97 0.018 282); }
.callout--brand::before { color: var(--brand); }
.callout--accent { border-color: oklch(0.85 0.08 30); background: oklch(0.97 0.020 30); }
.callout--accent::before { color: oklch(0.65 0.18 30); }
.callout--good { border-color: oklch(0.84 0.08 160); background: oklch(0.96 0.020 160); }
.callout--good::before { color: oklch(0.55 0.14 160); }

/* ---- Ranked tables (Slides 4, 5, 6, 7) ---- */
.rank-table {
  flex: 1;
  display: flex;
  flex-direction: column;
  border-collapse: collapse;
  font-size: 13px;
  min-height: 0;
}
.rank-table thead {
  display: block;
  flex: 0 0 auto;
}
.rank-table thead tr {
  display: grid;
  grid-template-columns: 32px minmax(160px, 220px) 1fr 140px;
  column-gap: 18px;
  align-items: center;
  border-bottom: 1px solid var(--hairline);
}
.rank-table thead th {
  text-align: left;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding: 10px 0;
}
.view--slides .rank-table thead th { color: var(--ink); }
.rank-table thead th.col-val { text-align: right; }
.rank-table tbody {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.rank-table tbody tr {
  flex: 1;
  display: grid;
  grid-template-columns: 32px minmax(160px, 220px) 1fr 140px;
  column-gap: 18px;
  align-items: center;
  border-bottom: 1px solid var(--hairline);
  min-height: 0;
}
.rank-table tbody tr:last-child { border-bottom: 0; }
.rank-table tbody td {
  padding: 0;
  vertical-align: middle;
}
.col-rank { color: var(--ink-mute); font-variant-numeric: tabular-nums; }
.view--slides .col-rank { color: var(--ink); }
.col-name { font-weight: 600; color: var(--ink); }
.view--slides .rank-table tbody .col-name { font-size: 18px; }

/* Top Products: keep 5 rows in view; the rest become a scrollable list. */
.slide[data-slide-name="Top Products"] .rank-table {
  min-height: 0;            /* allow the table to shrink inside flex parent */
}
/* Header gets the same right inset as the scrollable tbody so the "MARGIN"
   label right-aligns with the numbers in the rows below. The tbody has 18px
   padding-right AND the scrollbar (10px) takes additional space from the inner
   edge — so the header needs 28px to match. */
.slide[data-slide-name="Top Products"] .rank-table thead tr {
  padding-right: 28px;
  box-sizing: border-box;
}
.slide[data-slide-name="Top Products"] .rank-table tbody {
  overflow-y: auto;
  min-height: 0;
  -webkit-overflow-scrolling: touch;
  padding-right: 18px;                          /* breathing room between content and scrollbar track */
  /* Fade edges so rows feather in/out of view as they enter the scroll area. */
  mask-image: linear-gradient(to bottom, transparent 0%, #000 6%, #000 94%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 6%, #000 94%, transparent 100%);
  scrollbar-width: thin;                        /* Firefox */
  scrollbar-color: var(--hairline) oklch(0.22 0.005 280);
}
.slide[data-slide-name="Top Products"] .rank-table tbody tr {
  flex: 0 0 auto;          /* don't stretch — each row a fixed height so 5 fit at a time */
  min-height: 90px;
}
/* Slim, dark-friendly scrollbar (WebKit) with a visible "housing" track */
.slide[data-slide-name="Top Products"] .rank-table tbody::-webkit-scrollbar {
  width: 10px;
}
.slide[data-slide-name="Top Products"] .rank-table tbody::-webkit-scrollbar-track {
  background: oklch(0.22 0.005 280);
  border: 1px solid var(--hairline);
  border-radius: 999px;
  margin: 2px 0;
}
.slide[data-slide-name="Top Products"] .rank-table tbody::-webkit-scrollbar-thumb {
  background: var(--hairline);
  border-radius: 999px;
  border: 2px solid oklch(0.22 0.005 280);      /* inset thumb inside the track */
}
.slide[data-slide-name="Top Products"] .rank-table tbody::-webkit-scrollbar-thumb:hover {
  background: var(--ink-3);
}
.col-bar { /* bar lives here */ }
.col-val {
  text-align: right;
  display: flex; flex-direction: column; gap: 1px; align-items: flex-end;
  font-variant-numeric: tabular-nums;
}
.col-val .num { color: var(--ink); font-weight: 600; font-size: 14px; }
.col-val .num-mute { color: oklch(0.65 0.18 30); font-weight: 500; font-size: 13px; }
.col-val .meta { font-size: 11.5px; color: var(--ink-2); }

.ranked-bar {
  display: block;
  height: 2px;
  width: var(--w, 0%);
  background: var(--brand);
  border-radius: 999px;
  margin: 8px 0;
  transform-origin: left center;
  transition: width 700ms cubic-bezier(0.22, 1, 0.36, 1);
}
/* Shoot-out reveal when Top Products slide becomes active.
   Use scaleX (not width) so it doesn't fight the inline --w width. */
.slide[data-slide-name="Top Products"].is-active .ranked-bar {
  animation: barShoot 900ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.slide[data-slide-name="Top Products"].is-active tbody tr:nth-child(1) .ranked-bar { animation-delay: 120ms; }
.slide[data-slide-name="Top Products"].is-active tbody tr:nth-child(2) .ranked-bar { animation-delay: 200ms; }
.slide[data-slide-name="Top Products"].is-active tbody tr:nth-child(3) .ranked-bar { animation-delay: 280ms; }
.slide[data-slide-name="Top Products"].is-active tbody tr:nth-child(4) .ranked-bar { animation-delay: 360ms; }
.slide[data-slide-name="Top Products"].is-active tbody tr:nth-child(5) .ranked-bar { animation-delay: 440ms; }
.slide[data-slide-name="Top Products"].is-active tbody tr:nth-child(6) .ranked-bar { animation-delay: 520ms; }
.slide[data-slide-name="Top Products"].is-active tbody tr:nth-child(7) .ranked-bar { animation-delay: 600ms; }
.slide[data-slide-name="Top Products"].is-active tbody tr:nth-child(8) .ranked-bar { animation-delay: 680ms; }
.slide[data-slide-name="Top Products"].is-active tbody tr:nth-child(9) .ranked-bar { animation-delay: 760ms; }
.slide[data-slide-name="Top Products"].is-active tbody tr:nth-child(10) .ranked-bar { animation-delay: 840ms; }
@keyframes barShoot {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
.ranked-bar--accent { background: oklch(0.65 0.18 30); }
/* Top Products slide: profit line + dot use the primary green for consistency with Revenue Trend. */
.slide[data-slide-name="Top Products"] .ranked-bar--accent { background: oklch(0.65 0.14 160); }
.slide[data-slide-name="Top Products"] .dot--accent { background: oklch(0.65 0.14 160); }
.slide[data-slide-name="Top Products"] .col-val .num-mute { color: oklch(0.65 0.14 160); }
.ranked-bar--thin { height: 2px; }
.ranked-bar--pink { background: oklch(0.65 0.20 330); }

.margin-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  background: oklch(0.93 0.05 160);
  color: oklch(0.45 0.14 160);
  font-size: 11px;
  font-weight: 600;
}
.col-val__row {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  margin-top: 4px;
  align-self: flex-end;
}
.margin-pill--good { background: oklch(0.93 0.05 160); color: oklch(0.45 0.14 160); }

/* Slide 7 specifics */
.support-layout {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 18px;
  margin-top: 4px;
  min-height: 0;
}
.support-side {
  /* Horizontal row of individual chip cards. */
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  flex: 0 0 auto;
}
.support-stat {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 14px 14px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-chip);
  background: transparent;
  text-align: left;
}
.support-stat__label {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-3);
}
.support-stat__num {
  font-size: 18px; font-weight: 700; color: var(--ink);
  font-variant-numeric: tabular-nums; letter-spacing: -0.012em; line-height: 1.3;
}
.support-stat__num--good { color: oklch(0.65 0.14 160); }
.support-stat__sub {
  font-size: 18px;
  color: var(--ink-2);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---- Support pie chart: hero element on the slide ---- */
.support-pie {
  flex: 1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;          /* both cells share full row height — no overflow */
  gap: 12px;                     /* match support-side gap so legend aligns with chips above */
  min-height: 0;
  overflow: hidden;              /* safety net so nothing escapes the slide */
}
.support-pie__chart {
  display: block;
  aspect-ratio: 1;               /* keep the donut square regardless of cell shape */
  max-width: 100%;
  max-height: 100%;
  justify-self: center;          /* center the chart within its cell — aligns with chips 1+2 above */
  align-self: center;
  min-height: 0;
}
.support-pie__track {
  fill: transparent;
  stroke: oklch(0.30 0.005 280);
  stroke-width: 6;
}
.support-pie__seg {
  /* Solid wedges — no stroke means no anti-aliasing gaps at segment boundaries. */
  stroke: none;
}
.support-pie__seg--1 { fill: oklch(0.62 0.18 282); }
.support-pie__seg--2 { fill: oklch(0.60 0.20 312); }
.support-pie__seg--3 { fill: oklch(0.66 0.22 342); }
.support-pie__seg--4 { fill: oklch(0.72 0.18 12); }
.support-pie__seg--5 { fill: oklch(0.76 0.16 55); }
.support-pie__seg--6 { fill: oklch(0.82 0.14 95); }

.support-legend {
  margin: 0;
  /* Card treatment matching the stat chips above. The bottom padding stays
     small because the rows already fill the card via flex: 1 — extra padding
     here just creates an asymmetric gap below the last row. */
  padding: 12px 16px 4px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-chip);
  background: transparent;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 100%;
  align-self: stretch;
  max-height: 100%;
  min-height: 0;
}
.support-legend__title {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-3);
  margin-bottom: 4px;
}
.support-legend__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  flex: 1;
}
.support-legend__row {
  flex: 1;                                 /* every row gets the same slice of height */
  display: grid;
  grid-template-columns: 14px 1fr auto auto;
  align-items: center;                     /* content centered in its slice */
  column-gap: 12px;
  border-top: 1px solid var(--hairline);
  font-size: 18px;
  color: var(--ink-2);
  min-height: 0;
}
.support-legend__row:first-child { border-top: 0; }
.support-legend__dot {
  width: 10px;
  height: 10px;
  border-radius: 999px;
  align-self: center;
}
.support-legend__dot--1 { background: oklch(0.62 0.18 282); }
.support-legend__dot--2 { background: oklch(0.60 0.20 312); }
.support-legend__dot--3 { background: oklch(0.66 0.22 342); }
.support-legend__dot--4 { background: oklch(0.72 0.18 12); }
.support-legend__dot--5 { background: oklch(0.76 0.16 55); }
.support-legend__dot--6 { background: oklch(0.82 0.14 95); }
.support-legend__name { color: var(--ink); font-weight: 500; }
.support-legend__num {
  color: var(--ink);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.012em;
}
.support-legend__pct {
  color: var(--ink-2);
  font-size: 18px;
  font-variant-numeric: tabular-nums;
  min-width: 56px;
  text-align: right;
}

/* ---- Bottom nav ---- */
.slide-deck__nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 0 -28px -10px;
  padding: 14px 28px 4px;
  gap: 14px;
  flex: 0 0 auto;
}
/* Hide only the right side (page-num) on the cover — keep the period filter visible. */
.slide-deck.is-cover .slide-deck__nav-right { visibility: hidden; }

/* Cover slide stagger entrance — each element waits its turn. */
@keyframes slideStaggerIn {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}
.stagger-hidden { opacity: 0; }
.slide-stagger {
  animation: slideStaggerIn 760ms cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: var(--stagger-delay, 0ms);
}
.slide-deck__nav-left {
  display: flex; align-items: center; gap: 14px;
  opacity: 0;                                 /* hidden until the slide intro reveals it */
  transition: opacity 600ms ease;
}
.slide-deck__nav-left.is-in { opacity: 1; }
.slide-deck__nav-right {
  display: flex; align-items: center; gap: 12px;
}
.slide-arrow {
  position: relative;
  appearance: none;
  width: 52px; height: 52px;
  border: 1px solid var(--hairline);
  border-radius: 12px;
  background: #000;
  color: var(--ink-2);
  display: inline-grid; place-items: center;
  cursor: pointer;
  opacity: 0;                                 /* default: hidden until intro reveals */
  transition: color 160ms ease, border-color 160ms ease, background 220ms ease, opacity 600ms ease;
}
.slide-arrow.is-in { opacity: 1; }
.slide-arrow:disabled.is-in { opacity: 0.35; }
/* First-load attention state for the next arrow on the cover slide. */
.slide-arrow.is-fresh { border-color: var(--ink); }
.slide-deck.is-cover .slide-arrow[data-action="next"].is-fresh {
  animation: arrowGlow 3.4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.slide-arrow svg { width: 20px; height: 20px; }
@keyframes arrowGlow {
  0%, 100% {
    box-shadow: 0 0 0    0 oklch(0.98 0.005 80 / 0),
                0 0 0    0 oklch(0.98 0.005 80 / 0);
  }
  50% {
    /* Pure blur, no solid spread — reads as a soft halo, not a stroke. */
    box-shadow: 0 0 20px 2px oklch(0.98 0.005 80 / 0.24),
                0 0 40px 8px oklch(0.98 0.005 80 / 0.13);
  }
}
.slide-arrow:hover:not(:disabled) { color: var(--ink); border-color: var(--ink-3); }
.slide-arrow:disabled { cursor: default; }
/* On the cover slide, hovering the next arrow brightens the border to white
   AND intensifies the halo so the two effects read together. */
.slide-deck.is-cover .slide-arrow[data-action="next"].is-fresh:hover:not(:disabled) {
  border-color: var(--ink);
  animation: arrowGlowHover 1.6s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes arrowGlowHover {
  0%, 100% {
    box-shadow: 0 0 14px 2px oklch(0.98 0.005 80 / 0.35),
                0 0 32px 8px oklch(0.98 0.005 80 / 0.18);
  }
  50% {
    box-shadow: 0 0 26px 4px oklch(0.98 0.005 80 / 0.55),
                0 0 56px 14px oklch(0.98 0.005 80 / 0.28);
  }
}

.slide-deck__dots {
  display: inline-flex; gap: 6px;
  margin-left: 2px;
}
.slide-deck__dots span {
  width: 6px; height: 6px;
  border-radius: 999px;
  background: oklch(0.86 0.005 280);
  transition: width 220ms ease, background 220ms ease;
}
.slide-deck__dots span.is-active {
  width: 20px;
  background: var(--brand);
}

.slide-deck__name {
  font-size: 12px;
  color: var(--ink-2);
  letter-spacing: -0.005em;
  margin-left: 4px;
}

.slide-deck__filter-label {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
}
.slide-deck__filter-label::before {
  content: "⇅ ";
  letter-spacing: 0;
}
.slide-deck__page-num {
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.slide-deck.is-cover .slide-deck__page-num { visibility: hidden; }

.period-toggle {
  display: inline-flex;
  gap: 4px;
}
.period-btn {
  appearance: none;
  border: 1px solid var(--hairline);
  background: transparent;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--ink-2);
  cursor: pointer;
  transition: color 160ms ease, background 220ms ease, border-color 220ms ease;
}
.period-btn:hover { color: var(--ink); }
.period-btn.is-active {
  background: var(--brand);
  color: #fff;
  border-color: var(--brand);
  font-weight: 600;
}

/* No responsive reflow — the entire stage is scaled as a single unit via JS. */
@media (prefers-reduced-motion: reduce) {
  .line, .slider__halo { transition: none; }
  .prompt-card__caret { animation: none; }
}

/* ============================================
   PDF report view — three A4-proportioned pages
   in a vertically-scrolling card
   ============================================ */
.view--pdf {
  --pdf-ink:    oklch(0.22 0.025 250);
  --pdf-ink-2:  oklch(0.42 0.022 252);
  --pdf-ink-3:  oklch(0.55 0.020 250);
  --pdf-rule:   oklch(0.70 0.11 70);
  --pdf-navy:   oklch(0.22 0.045 252);
  --pdf-cream:  oklch(0.96 0.020 75);
  --pdf-divider:oklch(0.78 0.040 70);
  padding: 0;
  background: #272835;
  color: var(--pdf-ink);
  overflow: hidden;
  font-family: 'EB Garamond', 'Iowan Old Style', Georgia, serif;
}

.pdf-report {
  position: relative;
  height: 100%;
  border-radius: inherit;
  overflow: hidden;
}
/* Top + bottom fades using the gutter color — pages feather softly in/out of view. */
.pdf-report::before,
.pdf-report::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  pointer-events: none;
  z-index: 3;
}
.pdf-report::before {
  top: 0;
  height: 110px;
  background: linear-gradient(to bottom, #272835 0%, rgba(39, 40, 53, 0.6) 55%, rgba(39, 40, 53, 0) 100%);
}
.pdf-report::after {
  bottom: 0;
  height: 80px;
  background: linear-gradient(to top, #272835 0%, rgba(39, 40, 53, 0.6) 55%, rgba(39, 40, 53, 0) 100%);
  opacity: 1;
  transition: opacity 280ms ease;
}
.pdf-report.is-near-end::after { opacity: 0; }

.pdf-report__scroll {
  height: 100%;
  /* `scroll` (not `auto`) so the scrollbar gutter is always reserved on the
     right, even when the content fits without overflow. */
  overflow-y: scroll;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  /* Firefox: keep scrollbar-width CONSTANT (thin) — switching width on
     .is-scrolling resized the gutter mid-interaction and nudged content
     leftward. Only the color toggles. */
  scrollbar-width: thin;
  scrollbar-color: transparent transparent;
  scrollbar-gutter: stable;
  padding: 76px 56px 76px;     /* symmetric top/bottom padding so the last page breathes */
}
.pdf-report__scroll::-webkit-scrollbar { width: 10px; }
.pdf-report__scroll::-webkit-scrollbar-track { background: transparent; }
.pdf-report__scroll::-webkit-scrollbar-thumb {
  background: transparent;
  border-radius: 999px;
  transition: background 280ms ease;
}
/* Show the thumb only while the user is actively scrolling — width stays
   identical so no layout shift on either gecko or webkit. */
.pdf-report__scroll.is-scrolling { scrollbar-color: oklch(0.55 0.025 252) transparent; }
.pdf-report__scroll.is-scrolling::-webkit-scrollbar-thumb {
  background: oklch(0.50 0.025 252);
  border: 2px solid oklch(0.27 0.025 252);
}

.pdf-page {
  width: min(640px, calc(100% - 64px));
  aspect-ratio: 1 / 1.414;
  margin: 0 auto 24px;
  background: var(--pdf-cream);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.pdf-page:last-child { margin-bottom: 0; }

/* Top-right cluster holding the partner filter + print button.
   Positioned identically to the previous floating print button so its
   padding/placement is preserved exactly. */
.pdf-report__topbar {
  position: absolute;
  top: 18px;
  right: 26px;
  z-index: 5;
  display: flex;
  align-items: flex-end;
  gap: 10px;
}

/* Partner filter — label above the button, left-aligned. */
.pdf-filter {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
}
/* Filter label — matches .chip__label rhythm: small uppercase Inter label. */
.pdf-filter__label {
  font-family: var(--font);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: oklch(0.74 0.012 280);
  white-space: nowrap;
}
/* Dropdown button — chip-card aesthetic from the Revenue Forecast view. */
.pdf-dropdown {
  position: relative;
}
.pdf-dropdown__btn {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  background: transparent;
  border: 1px solid oklch(1 0 0 / 0.16);
  border-radius: var(--r-chip);
  color: oklch(0.97 0.005 280);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: -0.005em;
  text-transform: none;
  line-height: 1.1;
  cursor: pointer;
  outline: none;
  transition: background 200ms ease, border-color 200ms ease;
}
.pdf-dropdown__btn:hover {
  background: oklch(1 0 0 / 0.04);
  border-color: oklch(1 0 0 / 0.26);
}
.pdf-dropdown__btn:focus-visible {
  box-shadow: 0 0 0 2px oklch(0.62 0.18 282 / 0.45);
  border-color: oklch(0.62 0.18 282 / 0.55);
}
.pdf-dropdown__value { white-space: nowrap; }
.pdf-dropdown__chevron {
  width: 11px;
  height: 11px;
  flex-shrink: 0;
  color: oklch(0.85 0.008 280);
  transition: transform 220ms cubic-bezier(0.22, 1, 0.36, 1);
}
.pdf-dropdown[aria-expanded="true"] .pdf-dropdown__chevron,
.pdf-dropdown__btn[aria-expanded="true"] .pdf-dropdown__chevron {
  transform: rotate(180deg);
}

/* Dropdown panel — same card shape & hairline as the button, slight elevation. */
.pdf-dropdown__menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 100%;
  z-index: 10;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: oklch(0.21 0.018 252 / 0.96);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid oklch(1 0 0 / 0.14);
  border-radius: var(--r-chip);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
}
.pdf-dropdown__menu[hidden] { display: none; }
.pdf-dropdown__item {
  padding: 8px 12px;
  font-family: var(--font);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: -0.005em;
  text-transform: none;
  color: oklch(0.92 0.005 280);
  cursor: pointer;
  border-radius: 6px;
  white-space: nowrap;
  transition: background 140ms ease, color 140ms ease;
}
.pdf-dropdown__item:hover {
  background: oklch(1 0 0 / 0.06);
}
.pdf-dropdown__item.is-selected {
  background: oklch(0.62 0.18 282 / 0.20);
  color: oklch(0.98 0.005 280);
}

/* Scroll cue — just white text + arrow bottom-right, with a subtle bounce. */
.pdf-report__scroll-cue {
  position: absolute;
  bottom: 24px;
  right: 26px;
  z-index: 4;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: oklch(0.98 0.005 80);
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;
  font-size: 18px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  line-height: 1;
  pointer-events: none;
  animation: pdfScrollBounce 1.8s cubic-bezier(0.4, 0, 0.2, 1) infinite;
  transition: opacity 280ms ease;
}
.pdf-report__scroll-cue__label { display: inline-block; }
.pdf-report__scroll-cue svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: oklch(0.98 0.005 80);
}
.pdf-report__scroll-cue.is-hidden {
  opacity: 0;
}
@keyframes pdfScrollBounce {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(6px); }
}
@media (prefers-reduced-motion: reduce) {
  .pdf-report__scroll-cue { animation: none; }
}

/* Flash glow applied to text that just changed (filter / period selection). */
.pdf-flash {
  animation: pdfTextFlash 900ms cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes pdfTextFlash {
  0%   { text-shadow: 0 0 0 transparent; }
  25%  { text-shadow: 0 0 14px oklch(0.98 0.005 80 / 0.95), 0 0 28px oklch(0.98 0.005 80 / 0.55); }
  100% { text-shadow: 0 0 0 transparent; }
}

/* "To top" button — same pill styling as scroll-down, but clickable and only shown near the bottom. */
/* "To top" button — minimal text + arrow, matches the "Scroll down" cue. */
.pdf-report__top-cue {
  appearance: none;
  background: transparent;
  border: 0;
  position: absolute;
  bottom: 24px;
  right: 26px;
  z-index: 4;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 0;
  color: oklch(0.98 0.005 80);
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;
  font-size: 18px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 280ms ease;
  pointer-events: none;
}
.pdf-report__top-cue svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: oklch(0.98 0.005 80);
}
.pdf-report__top-cue.is-visible {
  opacity: 1;
  pointer-events: auto;
  animation: pdfTopBounce 1.8s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
@keyframes pdfTopBounce {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}
@media (prefers-reduced-motion: reduce) {
  .pdf-report__top-cue { animation: none; }
}

.pdf-report__print {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  background: transparent;
  border: 1px solid oklch(1 0 0 / 0.16);
  border-radius: var(--r-chip);
  color: oklch(0.97 0.005 280);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: -0.005em;
  text-transform: none;
  line-height: 1.1;
  cursor: default;
  position: relative;
  transition: background 200ms ease, border-color 200ms ease;
}
.pdf-report__print:hover {
  background: oklch(1 0 0 / 0.04);
  border-color: oklch(1 0 0 / 0.26);
}
.pdf-report__print svg { width: 14px; height: 14px; flex-shrink: 0; }
.pdf-report__print::after {
  content: 'Print, export, or share\A directly from Lightdash';
  position: absolute;
  top: calc(100% + 12px);
  right: 0;
  background: oklch(0.27 0.005 280);
  border-radius: 16px;
  padding: 16px 20px;
  width: max-content;
  color: oklch(0.95 0.005 280);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 15px;
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.4;
  text-transform: none;
  text-align: left;
  white-space: pre-line;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 160ms ease, transform 220ms cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
}
.pdf-report__print:hover::after { opacity: 1; transform: translateY(0); }
@keyframes pdfPrintGlow {
  0%, 100% { box-shadow: 0 0 0 0 oklch(0.70 0.11 70 / 0); }
  50%      { box-shadow: 0 0 18px 2px oklch(0.70 0.11 70 / 0.55), 0 0 36px 8px oklch(0.70 0.11 70 / 0.22); }
}

.pdf-page--cover {
  background: var(--pdf-navy);
  color: oklch(0.96 0.020 75);
  position: relative;
  padding: 80px 48px 36px;
  display: flex;
  flex-direction: column;
  /* Cover keeps the A4 aspect via the shared .pdf-page rule. To keep the meta
     visible on the fold, the body sits at the top and the meta block sits
     directly below it (with a fixed gap), not at the bottom of the page. */
}
.pdf-page--cover .pdf-cover__body {
  margin-top: 0;
  margin-bottom: 36px;       /* fixed gap between body and meta — meta stays within the fold */
}
.pdf-cover__rule-top {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: var(--pdf-rule);
}
.pdf-cover__confidential {
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--pdf-rule);
}
.pdf-cover__year {
  position: absolute;
  top: auto;
  bottom: 24px;              /* anchored to the bottom-right corner */
  right: -10px;
  font-family: 'EB Garamond', serif;
  font-size: 300px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1;
  color: oklch(0.96 0.020 75 / 0.07);
  pointer-events: none;
  user-select: none;
}
.pdf-cover__body {
  align-self: start;          /* left-align inside the flex column (was pushing right) */
  margin-bottom: 12px;
  position: relative;
  z-index: 1;
}
.pdf-cover__eyebrow {
  display: block;
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--pdf-rule);
  margin-bottom: 18px;
}
.pdf-cover__title {
  margin: 0 0 10px;
  font-family: 'EB Garamond', serif;
  font-size: clamp(46px, 5.5vw, 60px);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.02em;
  color: oklch(0.96 0.020 75);
}
.pdf-cover__divider {
  display: block;
  width: 48px;
  height: 2px;
  background: var(--pdf-rule);
  margin: 22px 0 18px;
}
.pdf-cover__lede {
  margin: 0;
  max-width: 40ch;
  font-family: 'EB Garamond', serif;
  font-size: 17px;
  line-height: 1.5;
  color: oklch(0.86 0.014 75);
}
.pdf-cover__meta {
  align-self: start;            /* prevent cross-axis stretch from the flex parent */
  display: grid;
  grid-template-columns: auto auto;
  column-gap: 64px;
  margin-bottom: 28px;          /* breathing room between meta and the title below */
  position: relative;
  z-index: 1;
}
.pdf-meta { display: flex; flex-direction: column; gap: 12px; }
.pdf-meta__label {
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;
  font-size: 8.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--pdf-rule);
}
.pdf-meta__value {
  font-family: 'EB Garamond', serif;
  font-size: 14px;
  color: oklch(0.96 0.020 75);
}

.pdf-page--paper { background: var(--pdf-cream); color: var(--pdf-ink); }

.pdf-page__head {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 36px;
  background: var(--pdf-navy);
  color: oklch(0.96 0.020 75);
  border-bottom: 2px solid var(--pdf-rule);
}
.pdf-page__num {
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.22em;
  color: var(--pdf-rule);
}
.pdf-page__title {
  margin: 0;
  font-family: 'EB Garamond', serif;
  font-size: 18px;
  font-weight: 400;
  letter-spacing: -0.005em;
  color: oklch(0.96 0.020 75);
}

.pdf-page__body {
  flex: 1;
  padding: 28px 36px 16px;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.pdf-page__lead {
  margin: 0 0 10px;
  font-family: 'EB Garamond', serif;
  font-size: 14px;
  line-height: 1.55;
  color: var(--pdf-ink);
}
.pdf-page__lead strong { font-weight: 600; }
.pdf-page__note {
  margin: 0 0 18px;
  font-family: 'EB Garamond', serif;
  font-size: 13px;
  font-style: italic;
  color: var(--pdf-ink-2);
}

.pdf-kpis {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18px;
  margin-top: 22px;
  margin-bottom: 18px;
}
.pdf-kpi { display: flex; flex-direction: column; }
.pdf-kpi__rule {
  height: 2px;
  width: 64px;
  background: var(--pdf-rule);
  margin-bottom: 10px;
}
.pdf-kpi__label {
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;
  font-size: 8.5px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--pdf-ink-2);
  margin-bottom: 6px;
}
.pdf-kpi__value {
  font-family: 'EB Garamond', serif;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.005em;
  line-height: 1;
  color: var(--pdf-ink);
  margin-bottom: 6px;
}
.pdf-kpi__sub {
  font-family: 'EB Garamond', serif;
  font-style: italic;
  font-size: 11px;
  color: var(--pdf-ink-2);
}

.pdf-divider {
  height: 1px;
  border: 0;
  background: var(--pdf-divider);
  margin: 8px 0 16px;
}

.pdf-narrative {
  display: grid;
  gap: 30px 56px;                 /* more breathing room between rows + columns */
  align-content: start;           /* don't distribute extra vertical space between rows */
  min-height: 0;
}
.pdf-narrative--2col { grid-template-columns: 1fr 1fr; grid-template-rows: auto auto; }
.pdf-narrative--3col { grid-template-columns: repeat(3, 1fr); }
.pdf-narrative section { display: flex; flex-direction: column; }
.pdf-narrative h3 {
  margin: 0 0 6px;
  font-family: 'EB Garamond', serif;
  font-size: 13px;
  font-weight: 600;
  color: var(--pdf-ink);
}
.pdf-narrative p {
  margin: 0;
  font-family: 'EB Garamond', serif;
  font-size: 12px;
  line-height: 1.55;
  color: var(--pdf-ink);
}

.pdf-page__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 36px;
  border-top: 1px solid var(--pdf-divider);
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;
  font-size: 8.5px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--pdf-ink-2);
}

.pdf-chart {
  position: relative;
  margin: 0 0 14px;
  padding: 0 0 0 30px;          /* tighter gutter so the title/SVG sit closer to the page's left edge */
}
.pdf-chart__head {
  margin-bottom: 14px;
  display: flex;
  flex-direction: row;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 10px;
}
.pdf-chart__title {
  font-family: 'EB Garamond', serif;
  font-size: 13px;
  font-weight: 600;
  color: var(--pdf-ink);
}
.pdf-chart__sub {
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;
  font-size: 8.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--pdf-ink-2);
}
.pdf-chart__svg { display: block; width: 100%; height: 240px; }
.pdf-chart__grid line {
  stroke: var(--pdf-divider);
  stroke-width: 1;
  stroke-dasharray: 2 4;
  vector-effect: non-scaling-stroke;
}
.pdf-chart__area { fill: none; }
.pdf-chart__line {
  fill: none;
  stroke-width: 1.5;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
.pdf-chart__line--rev    { stroke: oklch(0.45 0.16 252); }
.pdf-chart__line--profit { stroke: oklch(0.65 0.16 50);  }
.pdf-chart__y {
  position: absolute;
  left: 0;
  top: 40px;
  bottom: 56px;
  width: 24px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;
  font-size: 8px;
  color: var(--pdf-ink-3);
  text-align: right;
  pointer-events: none;
}
.pdf-chart__x {
  display: flex;
  justify-content: space-between;
  margin-top: 6px;
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;
  font-size: 7.5px;
  color: var(--pdf-ink-3);
}
.pdf-chart__legend {
  margin-top: 8px;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 16px;
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;
  font-size: 8.5px;
  color: var(--pdf-ink-2);
}
.pdf-chart__legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;                    /* matches the slideshow's .trend-legend__item gap */
}
.pdf-chart__dot {
  display: inline-block;
  width: 12px;
  height: 2px;
  border-radius: 999px;
}
.pdf-chart__dot--rev    { background: oklch(0.45 0.16 252); }
.pdf-chart__dot--profit { background: oklch(0.65 0.16 50); }

@media print {
  body * { visibility: hidden; }
  .view--pdf, .view--pdf * { visibility: visible; }
  .view--pdf {
    position: fixed;
    inset: 0;
    margin: 0;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    height: auto;
  }
  .pdf-report__scroll { overflow: visible; padding: 0; }
  .pdf-page { box-shadow: none; margin: 0 0 24px; }
  .pdf-report__print { display: none; }
}
