/* Pure HTML/CSS implementation of slide-primitives.jsx. */
.slide.sp-slide {
  position: relative;
  width: var(--slide-width);
  height: var(--slide-height);
  overflow: hidden;
  padding: 0;
  background: var(--paper);
  color: var(--text-body);
  font-family: var(--font-sans);
  font-weight: var(--font-weight-regular);
  letter-spacing: var(--tracking-body);
}

.sp-frame-content {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  padding: var(--slide-y) var(--slide-x);
}

.sp-gradient-bleed {
  position: absolute;
  inset: -12%;
  background: var(--grad-cover);
  filter: blur(var(--space-400));
}

.sp-grain {
  position: absolute;
  inset: 0;
  z-index: 1;
  background-image: var(--texture-grain);
  opacity: 0.5;
  mix-blend-mode: overlay;
  pointer-events: none;
}

/* Dark-surface grid — cover and thank-you only. Deliberately carries no z-index:
   each surface has a different stack, and DOM order is what keeps the dots above
   the grid on both. The cover overrides to z-index 1 because its grain and dots
   both sit at 1; the ending slide's layers are all `auto`, so plain DOM order
   already puts its beam dots on top. Never above .sp-frame-content (z-index 2). */
.sp-grid-texture {
  position: absolute;
  inset: 0;
  background-image: var(--texture-grid);
  background-size: var(--texture-grid-size);
  pointer-events: none;
}

.sp-title-slide .sp-grid-texture {
  z-index: 1;
}

.sp-kicker,
.sp-meta,
.sp-footnote,
.sp-comparison-label {
  margin: 0;
  font-family: var(--font-label);
  font-size: var(--type-label-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
}

.sp-kicker {
  line-height: 18px;
}

.sp-kicker-dark,
.sp-light-copy {
  color: var(--white-72);
}

.sp-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-100);
  margin-bottom: var(--space-400);
}

/* Scoped to .sp-slide so it outranks `.slide h2` (0,1,1) in styles.css —
   a bare .sp-header-title (0,1,0) loses to it and silently renders at
   header size. */
.sp-slide .sp-header-title,
.sp-showcase-copy .sp-header-title {
  margin: 0;
  max-width: 100%;
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
  color: var(--ink);
  text-wrap: balance;
}

.sp-lead {
  margin: 0;
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
}

/* Two classes for BOTH properties. `.slide.sp-slide` sets background and colour
   at (0,2,0), so a single-class rule here loses on specificity — the background
   already had the two-class form, but the colour did not, which left these dark
   slides inheriting --text-body. That is invisible on near-black, and it is what
   made the cover's subtitle unreadable when --white-82 went missing. With the
   root genuinely white, a future token failure degrades to white-on-dark instead
   of dark-on-dark. */
.slide.sp-title-slide,
.slide.sp-section-divider {
  background: var(--night);
  color: var(--paper);
}

.sp-title-logo {
  width: var(--title-logo-size);
  height: var(--title-logo-size);
  object-fit: contain;
}

.sp-title-copy {
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
  max-width: var(--content-case);
  margin-top: auto;
}

/* The name is the display element on this cover. 40/48 via --type-case-size —
   the existing display-title token, shared with the case openers — rather than a
   new size. Was --type-divider-size (44/52) when the h1 held "Product Designer". */
.sp-title-copy h1 {
  margin: 0;
  font-size: var(--type-case-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-case-line);
  /* Literal, not a token: every display tracking token in the deck is -0.025em
     and the design calls for -0.015em here. -0.4px looser across the name at
     40px. .sp-statement-copy h2 already carries the same raw value. */
  letter-spacing: -0.015em;
  color: var(--paper);
  text-wrap: balance;
}

/* The positioning line. max-width holds it to the design's measure — narrower
   than the copy column, so it breaks where the design breaks it. */
.sp-title-copy .sp-lead {
  max-width: 620px;
  text-wrap: pretty;
}

.sp-short-rule {
  width: var(--space-400);
  height: var(--border-thin);
  margin-top: var(--space-100);
  background: var(--rule-on-dark);
}

.sp-title-copy .sp-light-copy {
  color: var(--white-82);
}

/* margin-top: auto pins this to the stage bottom, so the name group above it
   floats between the logo and this line rather than stacking under the logo.
   The shared .sp-meta rule sets 14px but text-transform: none and tracking 0 —
   the cover's meta is the uppercase treatment, so both are set here. */
.sp-light-meta {
  margin-top: auto;
  color: var(--white-60);
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

.sp-title-dots {
  position: absolute;
  z-index: 1;
  aspect-ratio: 1;
  background-image: radial-gradient(rgba(102, 94, 253, 0.42) 1px, transparent 1px);
  pointer-events: none;
}

.sp-title-dots-one {
  right: -8%;
  bottom: -28%;
  width: 62%;
  background-size: var(--space-100) var(--space-100);
  mask-image: radial-gradient(circle, transparent 50%, #000 54%, #000 60%, transparent 64%);
}

.sp-title-dots-two {
  right: -14%;
  bottom: -34%;
  width: 80%;
  background-size: 9px 9px;
  mask-image: radial-gradient(circle, transparent 55%, #000 58%, #000 62%, transparent 65%);
}

.sp-title-blob {
  position: absolute;
  z-index: 0;
  aspect-ratio: 1;
  border-radius: var(--radius-pill);
  filter: blur(var(--cover-blob-blur));
  mix-blend-mode: screen;
  pointer-events: none;
}

.sp-title-blob-sky {
  top: 2%;
  right: -14%;
  width: 52%;
  background: radial-gradient(circle, var(--cover-blob-sky), transparent 62%);
}

.sp-title-blob-rose {
  right: 2%;
  bottom: -16%;
  width: 44%;
  background: radial-gradient(circle, var(--cover-blob-rose), transparent 62%);
}

@media (prefers-reduced-motion: no-preference) {
  .sp-title-animated .sp-gradient-bleed {
    animation: gc-breathe var(--motion-cover-bleed) ease-in-out infinite alternate;
  }

  .sp-title-animated .sp-title-blob-sky {
    animation: gc-blob-sky var(--motion-cover-sky) ease-in-out infinite alternate;
  }

  .sp-title-animated .sp-title-blob-rose {
    animation: gc-blob-rose var(--motion-cover-rose) ease-in-out infinite alternate;
  }

  @keyframes gc-breathe {
    from { transform: rotate(0deg) scale(1); }
    to { transform: rotate(-2.5deg) scale(1.08) translate(-1.5%, 1%); }
  }

  @keyframes gc-blob-sky {
    from { transform: translate(0, 0) scale(1); }
    to { transform: translate(-9%, 14%) scale(1.3); }
  }

  @keyframes gc-blob-rose {
    from { transform: translate(0, 0) scale(1.18); }
    to { transform: translate(7%, -12%) scale(0.88); }
  }
}

.slide.sp-case-opener {
  background: var(--grad-aurora);
}

.sp-case-copy {
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
  width: 100%;
  margin-top: auto;
}

.sp-case-copy h1 {
  margin: 0;
  /* Wider than --content-case deliberately: that token is shared by eight
     selectors and only the case thesis needs the extra measure. 760 puts
     "From Data Discovery to Governed Action" (719px) on one line; the
     lineage thesis keeps its authored break regardless. */
  max-width: 760px;
  font-size: var(--type-case-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-case-line);
  letter-spacing: var(--tracking-case);
  color: var(--ink);
  text-wrap: balance;
  white-space: pre-line;
}

.sp-case-meta {
  display: grid;
  grid-template-columns: repeat(var(--sp-case-meta-count, 4), minmax(0, 1fr));
  gap: var(--space-400);
  margin-top: var(--space-150);
  padding-top: var(--space-200);
  border-top: var(--border-thin) solid var(--hairline);
}

.sp-case-meta-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-100);
  min-width: 0;
}

.sp-case-meta-item span {
  font-family: var(--font-label);
  font-size: var(--type-label-size);
  line-height: var(--type-body-line);
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
}

.sp-case-meta-item strong {
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
  color: var(--ink);
  /* Same treatment the case thesis gets: an authored \n breaks the line, and
     everything without one wraps exactly as before. */
  white-space: pre-line;
}

.sp-metric-hero,
.sp-wash {
  background: var(--grad-wash);
}

.sp-metric-content {
  display: flex;
  flex-direction: column;
  gap: var(--space-400);
  margin: auto 0;
}

.sp-metric-headline {
  max-width: var(--content-case);
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
}

.sp-metric-headline span {
  background: var(--grad-type);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.sp-metric-grid {
  display: grid;
  grid-template-columns: repeat(var(--sp-metric-count), minmax(0, 1fr));
  gap: var(--space-600);
}

.sp-metric-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
}

.sp-metric-item strong {
  width: fit-content;
  font-size: var(--type-stat-multi-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-stat-line);
  color: var(--stat-neutral);
}

.sp-metric-primary strong {
  background: var(--grad-type);
  background-clip: text;
  color: transparent;
}

.sp-metric-single .sp-metric-item strong {
  font-size: var(--type-stat-single-size);
}

.sp-metric-item span {
  max-width: 260px;
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
  color: var(--muted);
}

.sp-footnote {
  max-width: 760px;
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--type-label-mono-size);
  font-weight: var(--font-weight-regular);
  line-height: 20px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
}

/* Flat: a footnote, neither an ordinal numeral nor headline emphasis. */
.sp-footnote-accent {
  width: fit-content;
  color: var(--blue);
}

.sp-problem-context .sp-header {
  margin-bottom: 0;
}

.sp-problem-grid {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  justify-content: center;
  gap: var(--space-200);
  max-width: var(--content-case);
}

.sp-problem-lead,
.sp-problem-body {
  margin: 0;
  font-weight: var(--font-weight-regular);
  text-wrap: pretty;
}

.sp-problem-lead {
  color: var(--ink);
  font-size: var(--type-lead-size);
  line-height: var(--type-context-line);
}

.sp-problem-body {
  color: var(--text-secondary);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
}

.sp-problem-facts {
  display: flex;
  gap: var(--space-700);
  padding-top: var(--space-250, 20px);
  border-top: var(--border-thin) solid var(--hairline);
}

.sp-problem-fact {
  display: flex;
  flex-direction: column;
  gap: var(--space-100);
}

.sp-problem-fact span,
.sp-problem-fact strong {
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
}

.sp-problem-fact span {
  color: var(--muted);
}

.sp-problem-fact strong {
  color: var(--ink);
}

/* ImpactSplit — two impact lenses with a single brand/voice footer. */
.sp-impact-split .sp-frame-content {
  padding-top: var(--space-700);
  padding-bottom: var(--space-700);
}

.sp-impact-split header {
  display: flex;
  flex-direction: column;
  gap: var(--space-100);
  margin-bottom: var(--space-500);
}

.sp-impact-split h2,
.sp-impact-split h3,
.sp-impact-split p,
.sp-impact-split blockquote {
  margin: 0;
}

.sp-impact-split h2 {
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
  text-wrap: balance;
}

.sp-impact-columns {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-700);
  padding-bottom: var(--space-350);
  border-bottom: var(--border-thin) solid var(--hairline);
}

.sp-impact-columns article {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: var(--space-100);
  row-gap: var(--space-100);
}

.sp-impact-columns b,
.sp-impact-columns h3 {
  color: var(--blue);
  font-size: var(--type-label-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-label-line);
}

.sp-impact-columns h3 {
  grid-column: 2;
}

.sp-impact-columns ul {
  grid-column: 1 / -1;
  display: grid;
  gap: var(--space-100);
  margin: 0;
  padding: 0;
  list-style: none;
}

.sp-impact-columns li {
  display: flex;
  gap: var(--space-100);
  color: var(--text-body);
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
}

.sp-impact-columns li::before {
  width: 5px;
  height: 5px;
  flex: none;
  margin-top: 9px;
  border-radius: var(--radius-pill);
  background: var(--muted);
  content: "";
}

.sp-impact-footer {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 1.1fr;
  gap: var(--space-700);
  align-items: center;
  margin-top: var(--space-400);
}

.sp-impact-footer aside {
  display: flex;
  min-height: 146px;
  align-items: center;
  justify-content: center;
  gap: var(--space-250);
  padding: 0 var(--space-400);
  border-radius: var(--radius-panel);
  background: var(--grad-type);
}

.sp-impact-footer aside img {
  max-width: 72%;
  height: 26px;
  filter: brightness(0) invert(1);
  object-fit: contain;
}

.sp-impact-footer aside span {
  color: var(--paper);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
}

.sp-impact-footer blockquote {
  display: flex;
  flex-direction: column;
  gap: var(--space-150);
}

.sp-impact-footer blockquote p {
  color: var(--ink);
  font-size: var(--type-compare-title-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-compare-title-line);
  letter-spacing: var(--tracking-header);
  text-wrap: pretty;
}

.sp-impact-footer cite {
  color: var(--muted);
  font-size: var(--type-label-size);
  font-style: normal;
  font-weight: var(--font-weight-regular);
  line-height: var(--type-label-line);
}

.sp-accordion-interactive .sp-frame-content {
  padding: var(--slide-y) calc(var(--slide-x) - var(--space-400));
}

.sp-accordion-with-context .sp-frame-content {
  padding-top: var(--space-300);
  padding-bottom: var(--space-300);
}

.sp-accordion-with-context .sp-accordion-interactive-copy {
  gap: var(--space-300);
}

.sp-accordion-with-context .sp-accordion-interactive-layout {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.sp-accordion-interactive-copy,
.sp-accordion-media-right .sp-accordion-interactive-copy {
  grid-column: 1;
  grid-row: 1;
}

.sp-accordion-interactive-media,
.sp-accordion-media-right .sp-accordion-interactive-media {
  grid-column: 2;
  grid-row: 1;
}

.sp-accordion-with-context .sp-accordion-interactive-header > p {
  font-size: var(--type-label-size);
  line-height: calc(var(--type-body-line) - var(--space-100) / 2);
}

.sp-accordion-with-context .sp-accordion-interactive-rows {
  padding-top: calc(var(--space-100) / 2);
  padding-bottom: calc(var(--space-100) / 2);
}

.sp-accordion-interactive-layout {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  flex: 1;
  min-height: 0;
  gap: var(--space-700);
  align-items: center;
}

.sp-accordion-interactive-media {
  align-self: center;
  overflow: hidden;
  border-radius: var(--radius-lg);
}

.sp-accordion-interactive-media > img,
.sp-accordion-interactive-media > .ds-image-placeholder {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* Match the canonical AccordionList SlideFrame (padX 48 / padY 64) so the
   copy column clears the right-hand panel with the caret icon. */
.sp-accordion-validation .sp-frame-content {
  padding: 64px 48px 64px var(--slide-inset-left);
}

.sp-accordion-validation .sp-accordion-interactive-layout {
  display: block;
  position: static;
}

.sp-accordion-validation .sp-accordion-interactive-copy {
  max-width: var(--slide-copy-width);
  height: 100%;
  justify-content: center;
}

/* Full-height aurora panel pinned to the right, matching ScreenShowcase
   (page 6). Absolutely positioned so it breaks out of the accordion's
   frame padding instead of shrinking to the image height; flex centering
   so the image sits in the true vertical middle of the panel.
   `align-self: stretch` is load-bearing: the containing block here is the
   flex `.sp-frame-content`, and for an out-of-flow child of a flex container
   the box-alignment properties still apply. The shared rule above sets
   `align-self: center`, which makes the box shrink to its content and then
   centre between the insets — so top/bottom 24 resolved to a 417px panel
   floating at 84/84 instead of the 537px the insets ask for. Stretch is what
   makes both insets bind. Do not replace this with an explicit height; the
   537 has to stay derived from the stage. */
.sp-accordion-validation .sp-accordion-interactive-media {
  position: absolute;
  align-self: stretch;
  top: var(--space-300);
  right: var(--space-300);
  bottom: var(--space-300);
  left: var(--slide-media-left);
  border-radius: var(--radius-xl);
  background:
    radial-gradient(60% 50% at 18% 8%, rgba(102, 94, 253, 0.34), transparent 60%),
    radial-gradient(50% 40% at 88% 28%, rgba(242, 169, 196, 0.38), transparent 65%),
    radial-gradient(55% 45% at 55% 95%, rgba(110, 195, 240, 0.38), transparent 60%),
    linear-gradient(160deg, #edeffb, #f6f1fa);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-300);
  box-sizing: border-box;
}

/* The photo fills the panel's content box rather than letterboxing inside it.
   `max-width`/`max-height` are cleared on purpose — with them the intrinsic
   ratio wins and the panel keeps a band of aurora above and below the shot. */
.sp-accordion-validation .sp-accordion-interactive-media > img,
.sp-accordion-validation .sp-accordion-interactive-media > .ds-image-placeholder {
  display: block;
  width: 100%;
  max-width: none;
  height: 100%;
  max-height: none;
  aspect-ratio: auto;
  border-radius: var(--radius-lg);
  object-fit: cover;
}

.sp-accordion-validation .sp-accordion-interactive-row summary {
  /* --ink closed as well as open: the shared rule opens a row by darkening it
     from --text-secondary, but these three read as headings either way. */
  color: var(--ink);
  font-size: 16px;
  line-height: 23px;
}

/* The answers sit a step under their questions. Scoped to this slide rather
   than the shared rules, and covering all three answer shapes so switching a
   row to bullets or problem/decision keeps the same size. */
.sp-accordion-validation .sp-accordion-text-answer,
.sp-accordion-validation .sp-accordion-bullets,
.sp-accordion-validation .sp-accordion-field {
  font-size: 14px;
  line-height: 22px;
}

.sp-accordion-media-stack-wrap {
  overflow: visible;
  border-radius: 0;
}

.sp-accordion-media-stack {
  display: flex;
  width: 100%;
  flex-direction: column;
  gap: var(--space-200);
}

.sp-accordion-media-stack > img,
.sp-accordion-media-stack > .ds-image-placeholder {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  border-radius: var(--radius-lg);
  object-fit: cover;
}

.sp-accordion-research .sp-frame-content {
  padding-top: var(--space-200);
  padding-bottom: var(--space-200);
}

.sp-accordion-research .sp-accordion-interactive-copy {
  grid-column: 1;
  grid-row: 1;
  align-self: center;
  gap: var(--space-150);
}

.sp-accordion-research .sp-accordion-interactive-layout {
  grid-template-columns: minmax(0, 0.94fr) minmax(0, 1.06fr);
  gap: var(--space-600);
  align-items: center;
}

.sp-accordion-research .sp-accordion-interactive-media {
  grid-column: 2;
  grid-row: 1;
  align-self: center;
}

.sp-accordion-research .sp-accordion-media-stack {
  position: relative;
  display: block;
  min-height: 0;
  aspect-ratio: 4 / 3;
  overflow: visible;
  transform: none;
}

.sp-accordion-research .sp-accordion-media-stack > img,
.sp-accordion-research .sp-accordion-media-stack > .ds-image-placeholder {
  position: absolute;
  width: 78%;
  height: auto;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-lg);
  background: var(--paper);
  box-shadow: var(--elevation-1);
  object-fit: contain;
}

.sp-accordion-research .sp-accordion-media-stack > :first-child {
  right: 0;
  bottom: 0;
}

.sp-accordion-research .sp-accordion-media-stack > :nth-child(2) {
  top: 0;
  left: 0;
  z-index: 1;
}

.sp-accordion-research .sp-accordion-interactive-row {
  display: block;
}

.sp-accordion-research .sp-accordion-interactive-row summary {
  padding: var(--space-100) 0;
  color: var(--ink);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
  letter-spacing: var(--tracking-body);
}

.sp-accordion-research .sp-accordion-interactive-row > div,
.sp-accordion-research .sp-accordion-interactive-row[open] > div {
  display: grid;
  padding: 0;
}

.sp-accordion-research .sp-accordion-interactive-row[open] > div > .sp-accordion-bullets {
  margin-bottom: var(--space-150);
}

.sp-accordion-research .sp-accordion-bullets {
  line-height: 22px;
}

.sp-accordion-interactive-copy {
  display: flex;
  min-width: 0;
  flex-direction: column;
  align-self: center;
  margin-top: var(--sp-accordion-copy-offset, 0px);
  gap: var(--space-300);
}

.sp-accordion-interactive-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-100);
}

.sp-accordion-interactive-header h2 {
  max-width: var(--content-case);
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
  text-wrap: balance;
}

.sp-accordion-interactive-header > p {
  max-width: var(--content-case);
  margin: 0;
  color: var(--text-body);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  text-wrap: pretty;
}

.sp-accordion-interactive-rows {
  display: flex;
  flex-direction: column;
}

.sp-accordion-interactive-row {
  border-bottom: var(--border-thin) solid var(--hairline);
}

.sp-accordion-interactive-row:last-child {
  border-bottom: 0;
}

/* Inactive (collapsed) state. --ink lives on [open] — do not promote this. */
.sp-accordion-interactive-row summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-200);
  padding: var(--space-200) 0;
  cursor: pointer;
  color: var(--text-secondary);
  font-size: var(--type-accordion-title-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-accordion-title-line);
  letter-spacing: var(--tracking-body);
  transition: color var(--motion-base) var(--ease-out);
}

.sp-accordion-mode-read .sp-accordion-interactive-row summary {
  padding: var(--space-150) 0;
}

.sp-accordion-interactive-row[open] summary {
  color: var(--ink);
}

.sp-accordion-interactive-row summary::marker {
  content: "";
}

.sp-accordion-interactive-row summary:focus {
  outline: none;
}

.sp-accordion-interactive-row summary:focus-visible {
  outline: var(--border-accent) solid var(--blue);
  outline-offset: calc(var(--border-thin) * -1);
}

.sp-accordion-row-title {
  flex: 1;
}

.sp-accordion-row-toggle {
  display: grid;
  width: 10px;
  height: 10px;
  flex: none;
  place-items: center;
  color: var(--muted);
  transition: transform var(--motion-base) var(--ease-out);
}

.sp-accordion-row-toggle svg {
  display: block;
  width: 10px;
  height: 10px;
  fill: currentColor;
}

/* 45, not 180: a plus turns into a close mark, where a chevron flipped. */
.sp-accordion-interactive-row[open] .sp-accordion-row-toggle {
  transform: rotate(45deg);
}

.sp-accordion-interactive-row > div {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--motion-base) var(--ease-out);
}

.sp-accordion-interactive-row[open] > div {
  grid-template-rows: 1fr;
}

.sp-accordion-text-answer {
  min-height: 0;
  margin: 0;
  overflow: hidden;
  color: var(--muted);
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: 26px;
  letter-spacing: var(--tracking-body);
  text-wrap: pretty;
}

.sp-accordion-interactive-row[open] > div > .sp-accordion-text-answer {
  margin: 0 0 18px;
}

.sp-accordion-bullets {
  min-height: 0;
  margin: 0;
  padding: 0 0 0 var(--space-250);
  overflow: hidden;
  color: var(--muted);
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: 26px;
  letter-spacing: var(--tracking-body);
  text-wrap: pretty;
}

.sp-accordion-bullets li + li {
  margin-top: var(--space-100);
}

.sp-accordion-interactive-row[open] > div > .sp-accordion-bullets {
  margin: 0 0 18px;
}

.sp-accordion-constraint-answer {
  display: flex;
  min-height: 0;
  overflow: hidden;
  flex-direction: column;
  gap: var(--space-100);
}

.sp-accordion-interactive-row[open] > div > .sp-accordion-constraint-answer {
  margin: 0 0 18px;
}

.sp-accordion-field {
  display: grid;
  grid-template-columns: var(--space-200) minmax(0, 1fr);
  gap: var(--space-100);
  margin: 0;
  color: var(--muted);
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: 26px;
  text-wrap: pretty;
}

.sp-accordion-field-icon {
  display: block;
  width: var(--space-200);
  height: var(--space-200);
  color: currentColor;
  fill: currentColor;
}

.sp-accordion-problem > .sp-accordion-field-icon {
  /* Keep the warning glyph informative without introducing a competing alert color. */
  color: var(--muted);
}

.sp-accordion-decision > .sp-accordion-field-icon {
  color: var(--accent);
}

/* CompareSlide — use options for an in-frame comparison; tag/image remains for routed states. */
.sp-compare-slide .sp-frame-content {
  display: flex;
  flex-direction: column;
  padding: var(--space-600) var(--space-700);
}

.sp-compare-copy {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: var(--space-250);
}

.sp-compare-copy h2 {
  margin: 0;
  text-align: center;
  text-wrap: balance;
  font-size: var(--type-lead-size);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
}

.sp-compare-copy h2 {
  color: var(--ink);
  font-size: var(--type-compare-title-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-compare-title-line);
  letter-spacing: var(--tracking-header);
}

.sp-compare-toggle,
.sp-compare-stage > .sp-compare-tag {
  position: absolute;
  z-index: 1;
  bottom: 14px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: var(--space-050);
  padding: var(--space-050);
  border: var(--border-thin) solid var(--hairline);
  border-radius: var(--radius-pill);
  background: var(--glass-fill-soft);
  box-shadow: var(--elevation-control);
  -webkit-backdrop-filter: blur(var(--space-150)) saturate(140%);
  backdrop-filter: blur(var(--space-150)) saturate(140%);
}

.sp-compare-stage > .sp-compare-tag {
  display: block;
  margin: 0;
  padding: var(--space-075) var(--space-200);
  color: var(--ink);
  font-size: var(--type-control-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-control-line);
  letter-spacing: var(--tracking-body);
  text-align: center;
  white-space: nowrap;
}

/* Inactive state. --ink lives on .active — do not promote this. */
.sp-compare-option {
  border: 0;
  border-radius: var(--radius-pill);
  padding: var(--space-075) var(--space-200);
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-sans);
  font-size: var(--type-control-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-control-line);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--motion-base) var(--ease-out), color var(--motion-base) var(--ease-out), box-shadow var(--motion-base) var(--ease-out);
}

.sp-compare-option.active {
  background: var(--paper);
  color: var(--ink);
  box-shadow: var(--elevation-control-active);
}

.sp-compare-stage {
  position: relative;
  display: flex;
  min-height: 0;
  flex: 1;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--mock-chrome);
}

.sp-compare-stage > .sp-compare-visual {
  width: 100%;
  height: 100%;
  border: 0;
  object-fit: cover;
}

.sp-compare-stage > .sp-compare-visual > .ds-image-placeholder {
  width: 100%;
  height: 100%;
}


.sp-diagram-canvas .sp-frame-content,
.sp-exploration .sp-frame-content {
  padding-top: var(--space-750);
  padding-bottom: var(--space-750);
}

.sp-diagram-canvas .sp-header {
  margin-bottom: var(--space-350);
}

.sp-diagram-visual {
  display: grid;
  flex: 1;
  min-height: 0;
  place-items: center;
}

.sp-diagram-visual > svg {
  display: block;
  max-width: 100%;
  max-height: 100%;
}

.sp-diagram-placeholder {
  display: grid;
  width: 100%;
  height: 100%;
  place-items: center;
  border: var(--border-thin) dashed var(--hairline);
  border-radius: var(--radius-md);
  color: var(--muted);
  font-family: var(--font-label);
  font-size: var(--type-body-size);
}

.sp-diagram-caption {
  margin: var(--space-300) 0 0;
  color: var(--muted);
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
  text-align: center;
}

.sp-explainer .sp-frame-content {
  padding: 0;
}

.sp-explainer-grid {
  position: relative;
  width: 100%;
  height: 100%;
}

.sp-explainer-copy {
  position: absolute;
  z-index: 1;
  top: 50%;
  left: var(--explainer-copy-left);
  width: var(--explainer-copy-width);
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
}

.sp-explainer-copy h2 {
  margin: 0;
  max-width: none;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
  text-wrap: balance;
}

.sp-explainer-visual {
  position: absolute;
  top: var(--space-300);
  right: var(--space-300);
  bottom: var(--space-300);
  left: var(--explainer-panel-left);
  display: grid;
  min-width: 0;
  overflow: hidden;
  padding: var(--space-300);
  box-sizing: border-box;
  border-radius: var(--radius-panel);
  background: var(--grad-aurora-panel);
  place-items: center;
}

.sp-explainer-visual img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.sp-explainer-visual > svg {
  display: block;
  width: 100%;
  height: auto;
  max-height: 100%;
}

.sp-explainer-visual > svg.sp-lineage-pipeline {
  width: 100%;
  max-width: 1040px;
  height: auto;
}

.sp-explainer-visual > iframe.sp-lineage-pipeline {
  display: block;
  width: 100%;
  max-width: 1040px;
  aspect-ratio: 1040 / 300;
  height: auto;
  border: 0;
  background: transparent;
}

/* Two classes on purpose: the base `.slide.sp-slide` rule sets a background and
   would otherwise win. The wash now lives on the card panel, not the slide. */
.sp-slide.sp-storyboard-steps {
  background: var(--paper);
}

/* The panel is `flex: 1`, so without a gap here it butts straight against the
   statement. Same 40px the sibling glass slide (.sp-hypothesis-*) uses. */
.sp-storyboard-steps .sp-frame-content {
  gap: var(--space-500);
}

.stage .sp-storyboard-steps {
  cursor: pointer;
}

.sp-storyboard-steps header > div {
  display: flex;
  flex-direction: column;
  gap: var(--space-250);
  max-width: 800px;
}

.sp-storyboard-steps header > div > i {
  width: var(--space-600);
  height: var(--border-rule);
  background: var(--grad-hairline);
}

.sp-storyboard-steps h2,
.sp-career-arc h2,
.sp-steps-copy h2 {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
  /* Authored break instead of balance: the column is narrow enough that the
     automatic split landed after "Every", which reads as a broken phrase. */
  white-space: pre-line;
}

.sp-storyboard-steps h2 span {
  background: var(--grad-type);
  background-clip: text;
  color: transparent;
}

/* The grid doubles as the washed panel the cards sit on. Gradient stack matches
   .sp-hypothesis-panel so the deck's two glass slides read as siblings. */
.sp-storyboard-grid {
  display: flex;
  flex: 1;
  min-height: 0;
  gap: var(--space-150);
  align-items: stretch;
  box-sizing: border-box;
  padding: var(--space-300);
  border-radius: var(--radius-xl);
  background:
    radial-gradient(60% 50% at 18% 8%, rgba(102, 94, 253, 0.34), transparent 60%),
    radial-gradient(50% 40% at 88% 28%, rgba(242, 169, 196, 0.38), transparent 65%),
    radial-gradient(55% 45% at 50% 110%, rgba(110, 195, 240, 0.35), transparent 62%),
    #f6f5fc;
}

/* No pinned height: the cards stretch to fill the panel, as in the handoff.
   A fixed height would overflow the panel once the statement gap is added. */
.sp-storyboard-card {
  display: flex;
  flex: 1;
  box-sizing: border-box;
  flex-direction: column;
  gap: var(--space-150);
  padding: var(--space-350);
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, 0.42);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  border: 1px solid rgba(255, 255, 255, 0.85);
  transition: opacity var(--motion-slow) var(--ease-out), transform var(--motion-slow) var(--ease-out);
}

.sp-storyboard-card small,
.sp-career-card small {
  color: var(--muted);
  font-size: var(--type-label-size);
  font-weight: var(--font-weight-regular);
  line-height: 18px;
}

/* Overrides the shared `.sp-storyboard-card small, .sp-career-card small` rule
   above for storyboard only — career phase labels keep their own treatment. */
.sp-storyboard-card small {
  color: var(--blue);
  font-size: 12px;
  font-weight: var(--font-weight-medium, 500);
  line-height: var(--type-label-line);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* Sentence case, unlike every other card label in the deck (storyboard, light
   meta, table headers and five more all stay uppercase + 0.12em). Deliberate and
   scoped to slide 4: the phase label sits right under a milestone title, where
   shouting competes with it.
   NOTE: --font-mono below is a misnomer — it resolves to "DM Sans", sans-serif
   (gradation-tokens.css:93), so this label has never actually been monospace.
   Left as-is rather than silently switching faces; the token is worth renaming. */
.sp-career-card small {
  font-family: var(--font-mono);
  font-size: var(--type-career-phase-size);
  line-height: var(--type-body-line);
  letter-spacing: 0;
  white-space: nowrap;
}

.sp-storyboard-card p,
.sp-career-card p {
  margin: 0;
  color: var(--text-body);
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
  text-wrap: pretty;
}

.sp-storyboard-pending {
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
}

.sp-storyboard-arrow {
  align-self: center;
  color: var(--blue);
  font-size: var(--type-lead-size);
  font-style: normal;
}

/* OptionReveal — one direction per slide. The media panel is intentionally
   source-agnostic so screenshots can be replaced with live HTML prototypes. */
.sp-option-reveal .sp-frame-content {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--option-reveal-copy-width);
  gap: var(--space-600);
  align-items: stretch;
  padding-top: var(--space-600);
  padding-bottom: var(--space-600);
}

.sp-option-reveal-media {
  min-width: 0;
  overflow: hidden;
  border: var(--border-thin) solid var(--hairline);
  border-radius: var(--radius-panel);
  background: var(--panel);
}

.sp-option-reveal-media-rejected { border-color: var(--status-rejected-border); }
.sp-option-reveal-media-chosen { border-color: var(--status-chosen-border); }

.sp-option-reveal-media > img,
.sp-option-reveal-media > iframe,
.sp-option-reveal-media > .ds-image-placeholder {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  object-fit: cover;
}

.sp-option-reveal-demo .sp-frame-content {
  display: block;
  padding: 0;
}

.sp-option-reveal-demo-stage {
  position: absolute;
  /* 84px of headroom. The status block is absolutely placed, so its height
     cannot push this down — and it is taller on the AI option slides, where the
     status is set at 20px/28px, than on the lineage ones at 14px/18px. 84 clears
     the taller case (summary ends at 74) with room to breathe, and keeps all
     five option slides on the same geometry. */
  inset: 84px var(--space-300) var(--space-300);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Label and prototype share one column at the box's exact width, so the label
   tracks the box's right edge instead of the slide's — the box is centred and
   max-width-capped, which no static offset can follow. */
.sp-option-reveal-demo-frame {
  display: flex;
  flex-direction: column;
  width: var(--sp-option-demo-box-width);
  max-width: 100%;
  max-height: 100%;
}

.sp-option-reveal-demo-media {
  position: relative;
  width: 100%;
  height: var(--sp-option-demo-box-height);
  max-width: 100%;
  min-height: 0;
  overflow: hidden;
  border: var(--border-thin) solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--mock-chrome);
}

.sp-option-reveal-demo-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: var(--sp-option-demo-width);
  height: var(--sp-option-demo-height);
  transform: scale(var(--sp-option-demo-scale));
  transform-origin: top left;
}

.sp-option-reveal-demo-poster,
.sp-option-reveal-demo-iframe {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

.sp-option-reveal-demo-poster {
  z-index: 1;
  object-fit: cover;
  transition: opacity 160ms var(--ease-out);
}

.sp-option-reveal-demo-iframe {
  z-index: 2;
  border: 0;
  background: var(--panel);
  opacity: 0;
  transition: opacity 160ms var(--ease-out);
}

.sp-option-reveal-demo-canvas.is-demo-ready > .sp-option-reveal-demo-poster {
  opacity: 0;
}

.sp-option-reveal-demo-canvas.is-demo-ready > .sp-option-reveal-demo-iframe {
  opacity: 1;
}

/* Two rows: the tone bar and status on the first, the summary on the second,
   sharing one column so the summary's left edge lands on the status text. A
   grid rather than a fixed offset — the summary used to be absolutely placed
   22px down, which assumed an 18px status line and collided the moment the
   status was retyped larger. */
.sp-option-reveal-demo-status {
  position: absolute;
  top: var(--space-250);
  /* Offset back by the tone bar and its gap so the STATUS TEXT lands on the
     axis, not the bar. The prototype frame deliberately stays at its own
     inset — the axis governs type, not media. */
  left: calc(var(--slide-inset-left) - 13px);
  right: var(--space-300);
  z-index: 2;
  display: grid;
  grid-template-columns: 3px minmax(0, 1fr);
  align-items: stretch;
  column-gap: 10px;
  row-gap: 6px;
}

.sp-option-reveal-demo-status-bar {
  grid-row: 1;
  grid-column: 1;
  width: 3px;
  border-radius: 2px;
}

.sp-option-reveal-demo-status > .sp-option-reveal-demo-status-text {
  grid-row: 1;
  grid-column: 2;
  justify-self: start;
}

.sp-option-reveal-demo-status > .sp-option-reveal-demo-summary {
  grid-row: 2;
  grid-column: 2;
  position: static;
  max-width: none;
}

.sp-option-reveal-status-chosen .sp-option-reveal-demo-status-bar {
  background: var(--grad-status-chosen-bar);
}

.sp-option-reveal-status-rejected .sp-option-reveal-demo-status-bar {
  background: var(--grad-status-rejected-bar);
}

.sp-option-reveal-demo-status-text {
  display: flex;
  align-items: center;
  font-size: 14px;
  line-height: 18px;
  font-weight: 500;
  white-space: nowrap;
}

.sp-option-reveal-demo-summary {
  /* Under the status rather than floating over the mock: the pill sat on top of
     the prototype it was describing. Left edge lines up with the status text,
     which clears the 3px tone bar plus its gap. */
  position: absolute;
  top: calc(var(--space-250) + 22px);
  left: calc(var(--space-300) + 13px);
  z-index: 2;
  max-width: calc(100% - var(--space-2xl));
  margin: 0;
  color: var(--text-secondary);
  font-size: var(--type-label-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-label-line);
  white-space: nowrap;
}

.sp-option-reveal-demo-toggle {
  position: absolute;
  right: calc(var(--space-300) + var(--space-150));
  bottom: calc(var(--space-300) + var(--space-150));
  z-index: 4;
  display: inline-flex;
  align-items: center;
  gap: var(--space-075);
  margin: 0;
  padding: var(--space-100) var(--space-150);
  border: var(--border-thin) solid var(--glass-border);
  border-radius: var(--radius-md);
  background: var(--glass-fill);
  box-shadow: var(--elevation-control);
  color: var(--ink);
  font: var(--font-weight-regular) var(--type-label-size) / var(--type-label-line) var(--font-sans);
  cursor: pointer;
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  backdrop-filter: blur(12px) saturate(140%);
}

/* Scoped away from the count badge so only the caret rotates. */
.sp-option-reveal-demo-toggle span:not(.sp-option-reveal-demo-toggle-count) {
  transition: transform var(--motion-base) var(--ease-out);
}

.sp-option-reveal-demo.is-tradeoffs-open .sp-option-reveal-demo-toggle span:not(.sp-option-reveal-demo-toggle-count) {
  transform: rotate(180deg);
}

.sp-option-reveal-demo-toggle-count {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.sp-option-reveal-demo-tradeoffs {
  position: absolute;
  right: var(--space-300);
  /* 16px clear of the See trade-offs button (measured, not assumed: the button
     sits 36px off the bottom and is ~38px tall). */
  bottom: calc(var(--space-300) + var(--space-600) + 18px);
  z-index: 3;
  display: grid;
  width: min(420px, calc(100% - var(--space-2xl)));
  grid-template-rows: 0fr;
  overflow: hidden;
  border: var(--border-thin) solid transparent;
  border-radius: var(--radius-lg);
  background: var(--glass-fill);
  box-shadow: var(--elevation-control);
  opacity: 0;
  pointer-events: none;
  transition: grid-template-rows var(--motion-base) var(--ease-out), opacity var(--motion-base) var(--ease-out), border-color var(--motion-base) var(--ease-out);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  backdrop-filter: blur(12px) saturate(140%);
}

.sp-option-reveal-demo.is-tradeoffs-open .sp-option-reveal-demo-tradeoffs {
  grid-template-rows: 1fr;
  border-color: var(--glass-border);
  opacity: 1;
  pointer-events: auto;
}

.sp-option-reveal-demo-tradeoffs > ul {
  display: flex;
  min-height: 0;
  flex-direction: column;
  gap: var(--space-100);
  margin: 0;
  padding: var(--space-200);
  overflow: hidden;
  list-style: none;
}

.sp-option-reveal-demo-tradeoffs li {
  display: flex;
  gap: var(--space-100);
  align-items: flex-start;
  color: var(--ink);
  font-size: var(--type-label-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-label-line);
  white-space: nowrap;
}

/* Circular badges instead of bare +/- glyphs, in the same tones as the status
   bar so the verdict and its reasons read as one system. */
.sp-option-reveal-demo-tradeoffs li i {
  flex: none;
  width: 17px;
  height: 17px;
  margin-top: 1.5px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: var(--font-weight-semibold, 600);
  font-style: normal;
  line-height: 1;
}

.sp-option-reveal-demo-tradeoffs .sp-option-reveal-pros li i {
  background: rgba(52, 168, 125, 0.16);
  color: #0f7a5a;
}

.sp-option-reveal-demo-tradeoffs .sp-option-reveal-cons li i {
  background: rgba(226, 124, 160, 0.2);
  color: #b23a5f;
}

/* Frame label lives in slide space above the panel, never inside it: Option B's
   capture includes the app's own search bar, which an inside label would sit on. */
.sp-option-reveal-frame-label {
  /* Rendered even when empty, and always 22px tall with its margin, so every
     option slide reserves the same strip and the prototypes below stay the same
     size — the demo scale math in optionReveal() subtracts exactly this. */
  flex: none;
  min-height: 16px;
  margin-bottom: 6px;
  line-height: 16px;
  text-align: right;
  color: var(--muted);
  font-size: 12px;
  font-weight: var(--font-weight-semibold, 600);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  pointer-events: none;
}

.sp-option-reveal-demo-tradeoffs .sp-option-reveal-cons li {
  color: var(--muted);
}

.sp-option-reveal-copy {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: var(--space-100);
}

.sp-option-reveal-label,
.sp-option-reveal-tradeoffs > p,
.sp-option-reveal-verdict > p {
  margin: 0;
  font-size: var(--type-label-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-label-line);
  letter-spacing: 0;
}

/* Flat: a small label, neither an ordinal numeral nor headline emphasis. */
.sp-option-reveal-label {
  width: fit-content;
  color: var(--blue);
}

.sp-option-reveal-copy h2 {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
  text-wrap: balance;
}

.sp-option-reveal-status {
  width: fit-content;
  padding: var(--space-100) var(--space-150);
  border: var(--border-thin) solid var(--hairline);
  border-radius: var(--radius-sm);
  background: var(--paper);
  box-shadow: var(--elevation-control-active);
  font-size: var(--type-label-size);
  font-weight: 500;
  line-height: var(--type-label-line);
}

.sp-option-reveal-status-rejected { color: var(--status-rejected); }
.sp-option-reveal-status-chosen { color: var(--status-chosen); }

.sp-option-reveal-list,
.sp-option-reveal-list ul,
.sp-option-reveal-tradeoffs {
  display: flex;
  flex-direction: column;
}

.sp-option-reveal-list {
  gap: var(--space-100);
  margin-top: var(--space-150);
}

.sp-option-reveal-list ul {
  gap: var(--space-100);
  margin: 0;
  padding: 0;
  list-style: none;
}

.sp-option-reveal-list li {
  display: flex;
  gap: var(--space-150);
  color: var(--ink);
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
}

.sp-option-reveal-list li i {
  flex: none;
  font-style: normal;
}

.sp-option-reveal-tradeoffs { gap: var(--space-100); }
.sp-option-reveal-tradeoffs > p { color: var(--muted); }
.sp-option-reveal-tradeoffs li { color: var(--muted); }
.sp-option-reveal-tradeoffs:not(.is-open) ul { display: none; }

.sp-option-reveal-verdict {
  display: flex;
  flex-direction: column;
  gap: var(--space-100);
  margin-top: auto;
  padding-top: var(--space-150);
  border-top: var(--border-thin) solid var(--hairline);
}

.sp-option-reveal-verdict > p { color: var(--muted); }
.sp-option-reveal-verdict > span {
  color: var(--text-body);
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
  text-wrap: pretty;
}

.sp-career-arc header {
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
  max-width: 720px;
}

.sp-career-arc .sp-frame-content {
  padding-top: var(--space-700);
  padding-bottom: var(--space-700);
}

.sp-career-track {
  position: relative;
  flex: 1;
  min-height: 0;
  margin-top: var(--career-track-margin-top);
}

.sp-career-track > div {
  position: absolute;
  right: 0;
  left: 0;
  top: 50%;
  height: var(--border-thin);
  background: var(--hairline);
  transform: translateY(-50%);
}

.sp-career-track > section {
  /* Activates the z-index below. Without it this is neither positioned nor a
     flex/grid item — it is a grid CONTAINER inside a block parent — so the
     z-index was inert and the absolutely-positioned rail painted over the
     milestone dots. Lifts the whole milestone layer, stems and cards included. */
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(var(--sp-career-count, 3), minmax(0, 1fr));
  width: 100%;
  height: 100%;
  gap: var(--career-track-gap);
}

.sp-career-milestone {
  display: grid;
  grid-template-rows: 1fr var(--career-dot-size) 1fr;
  justify-items: start;
}

.sp-career-upper,
.sp-career-lower {
  display: flex;
  flex-direction: column;
  gap: var(--career-block-gap);
}

.sp-career-upper {
  justify-content: flex-end;
}

.sp-career-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-100);
}

.sp-career-card h3 {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-career-title-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-career-title-line);
  white-space: nowrap;
}

.sp-career-logos {
  display: flex;
  align-items: center;
  gap: var(--space-150);
  min-height: 18px;
}

.sp-career-logos img {
  display: block;
  width: auto;
  height: 18px;
}

/* The Dior wordmark is far wider than the other marks at a shared height, so
   the handoff sizes it down on its own. Matched by src rather than a new class
   so the careerArc markup stays as-is. */
/* Sized toward a ~14px letterform rather than a common box height, because these
   marks carry wildly different amounts of padding. Measured on the rendered
   images: DIOR fills its box, so 14 is 14. Select Star's and Snowflake's
   wordmarks are 0.70 and 0.55 of theirs, so their boxes have to run taller to
   put the same amount of letter on screen.
   bibigo and CJ are badge marks — their type sits inside a container, so there
   is no letterform to match and they stay on the 18px default. */
.sp-career-logos img[src*="dior" i] {
  height: 14px;
}

.sp-career-logos img[src*="select-star" i] {
  height: 20px;
}

.sp-career-logos img[src*="snowflake" i] {
  height: 25px;
}

/* Career-arc logos are credentials, not credibility signals — they recede so the
   role titles lead. brightness(0) collapses every non-transparent pixel to one
   colour regardless of hue; opacity lifts it to grey. Scoped to .sp-career-arc:
   the quote slides keep brand colour, and this filter would flatten the
   Amplitude and Intercom icon knockouts into solid shapes.
   stratifi is handled separately below — it is an app icon, not a wordmark. */
.sp-career-arc img[src*="/logos/"]:not([src*="stratifi"]) {
  filter: brightness(0) opacity(0.5);
}

/* stratifi.avif is a green rounded-square app icon. brightness(0) would collapse
   it to a featureless square — which is why it used to sit here unfiltered, in
   colour, as the only mark on the slide that did not recede. grayscale drops the
   hue while keeping the luminance inside the square, so the bolt stays readable
   and the mark carries the same weight as the wordmarks beside it. */
.sp-career-arc img[src*="stratifi"] {
  filter: grayscale(1) opacity(0.5);
}

.sp-career-milestone i {
  width: var(--border-thin);
  height: var(--career-tick-height);
  margin-left: 4px;
  background: var(--hairline);
}

/* The brand mark itself, not an outlined circle — the handoff drops the same
   gradient dot on the timeline. url() resolves against this file at the deck
   root, so it is correct for both the portfolio/ and presentation/ entries. */
.sp-career-milestone > b {
  width: var(--career-dot-size);
  height: var(--career-dot-size);
  box-sizing: border-box;
  background: url("assets/images/chloe-kim-logo.svg") center / contain no-repeat;
}

.sp-career-lower { grid-row: 3; }

.sp-career-card p {
  line-height: var(--type-career-body-line);
}

.sp-steps-diagram .sp-frame-content {
  display: block;
  padding: 0;
}

.sp-steps-copy {
  position: absolute;
  z-index: 1;
  top: 50%;
  left: var(--steps-copy-left);
  width: var(--steps-copy-width);
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: var(--space-250);
}

.sp-steps-copy > div {
  display: flex;
  flex-direction: column;
  /* Tighter than the --space-200 the other two numbered lists use: these
     rows are bare titles with no body copy under them, so they read as one
     group. No token sits at 10px. */
  gap: 10px;
}

.sp-steps-copy article {
  display: grid;
  grid-template-columns: var(--space-500) minmax(0, 1fr);
  gap: var(--space-150);
  /* Numerals sit ON the axis, with the titles indented past them — the same
     convention as the contents slide, the showcase decisions and the spotlight
     steps. These briefly hung outside the margin instead so the titles could
     meet the kicker, which made this the one numbered list in the deck whose
     numerals started left of everything else. */
}

/* Slide 24's *active* step treatment, applied to every row — this list is static
   and has no current step, so there is no inactive state to represent. The
   numeral is a 13px marker, not a 20px heading: at 20px it outsized the 18px
   title it marks. Matches .sp-step-spotlight-num / -step-title. */
.sp-steps-copy article > b {
  background: var(--grad-type);
  background-clip: text;
  color: transparent;
  font-family: var(--font-label);
  font-variant-numeric: tabular-nums;
  font-size: var(--type-control-size);
  font-weight: var(--font-weight-regular);
  letter-spacing: 0.08em;
  line-height: var(--type-body-line);
}

.sp-steps-copy article > div { display: flex; flex-direction: column; gap: 4px; }
.sp-steps-copy h3, .sp-steps-copy p { margin: 0; }
.sp-steps-copy h3 { color: var(--ink); font-size: var(--type-card-title-size); font-weight: var(--font-weight-medium, 500); line-height: var(--type-card-title-line); }
.sp-steps-copy p { color: var(--text-secondary); font-size: var(--type-body-size); font-weight: var(--font-weight-regular); line-height: 23px; }

.sp-steps-visual {
  position: absolute;
  top: var(--space-300);
  right: var(--space-300);
  bottom: var(--space-300);
  left: var(--steps-panel-left);
  display: grid;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  padding: var(--space-300);
  box-sizing: border-box;
  /* --radius-xl, not --radius-panel: matches .sp-step-spotlight-media on slide
     24, which does the same job beside the same copy column. Scoped to this rule
     because --radius-panel (16px) is shared with four unrelated panels. */
  border-radius: var(--radius-xl);
  background: var(--grad-aurora-panel);
  place-items: center;
}

.sp-steps-visual img,
.sp-steps-visual svg,
.sp-steps-visual iframe {
  display: block;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.sp-steps-visual iframe {
  width: 100%;
  height: 100%;
  border: 0;
}

.lineage-diagram {
  width: 100%;
  max-width: 680px;
  color: var(--ink);
  font-family: var(--font-sans);
}

.lineage-stage-labels,
.lineage-card-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-150);
}

.lineage-stage-labels {
  margin-bottom: var(--space-150);
}

.lineage-stage-labels span {
  color: var(--muted);
  font-size: 10px;
  font-weight: var(--font-weight-regular);
  line-height: 1;
  letter-spacing: 0.08em;
  text-align: center;
  text-transform: uppercase;
}

.lineage-node-card {
  position: relative;
  z-index: 1;
  box-sizing: border-box;
  height: 136px;
  padding: var(--space-200);
  border: var(--border-thin) solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--paper);
  cursor: pointer;
  outline: none;
  transition: transform var(--motion-slow) var(--ease-out), border-color var(--motion-slow) var(--ease-out), box-shadow var(--motion-slow) var(--ease-out);
}

.lineage-node-card::before {
  content: "";
  position: absolute;
  z-index: 2;
  inset: -1.5px;
  border-radius: inherit;
  padding: 1.5px;
  background: var(--grad-hover);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--motion-slow) var(--ease-out);
}

.lineage-node-card:hover,
.lineage-node-card:focus {
  border-color: transparent;
  /* Not elevation — a hover/focus state. It lifts with the transform below, so
     the shadow belongs to the interaction rather than to the card's resting
     depth, and does not follow --elevation-card. */
  box-shadow: 0 12px 28px rgba(13, 37, 61, 0.1);
  transform: translateY(-3px);
}

.lineage-node-card:hover::before,
.lineage-node-card:focus::before {
  opacity: 1;
}

.lineage-connector {
  position: absolute;
  top: 50%;
  left: calc(100% + 1px);
  width: calc(var(--space-150) + 1px);
  border-top: 1.5px dashed rgba(102, 94, 253, 0.7);
  pointer-events: none;
}

.lineage-node-heading {
  display: flex;
  align-items: center;
  gap: var(--space-100);
}

/* PRODUCT-MOCK PALETTE — .lineage-* imitates the Select Star lineage graph.
   The raw hex values below are that product's colours, not deck tokens. Do not
   convert them to --ink / --muted / --blue: a mock painted in deck colours stops
   reading as a screenshot of another product and starts reading as fake. */
.lineage-node-icon {
  display: grid;
  width: 30px;
  height: 30px;
  flex: none;
  place-items: center;
  border-radius: var(--radius-sm);
  border: 1px solid #ddd6fe;
  background: #f4f2ff;
  color: #6e56f0;
}

.lineage-node-icon svg {
  width: 17px;
  height: 17px;
  fill: currentColor;
}

.lineage-node-heading strong {
  min-width: 0;
  font-size: 12px;
  font-weight: 500;
  line-height: 16px;
  white-space: nowrap;
}

.lineage-node-card > p {
  margin: var(--space-250) 0 0;
  color: var(--muted);
  font-size: 10.5px;
  font-weight: var(--font-weight-regular);
  line-height: 18px;
}

.lineage-question-curves {
  display: block;
  width: 100%;
  height: 56px;
  overflow: visible;
}

.lineage-question-curves path {
  fill: none;
  stroke: var(--hairline);
  stroke-dasharray: 3 7;
  stroke-width: 1.25;
}

.lineage-question-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-300);
}

.lineage-question-grid p,
.lineage-question-grid span {
  margin: 0;
  font-size: 11px;
  font-weight: var(--font-weight-regular);
  line-height: 16px;
}

.lineage-question-grid p {
  color: var(--ink);
  display: flex;
  gap: var(--space-100);
}

.lineage-question-grid b {
  flex: none;
  color: var(--accent);
  font-weight: 600;
}

.lineage-question-grid span {
  display: block;
  margin: 3px 0 0 20px;
  color: var(--muted);
}

@media (prefers-reduced-motion: reduce) {
  .lineage-node-card,
  .lineage-node-card::before {
    transition: none;
  }
}

.sp-explainer-placeholder {
  color: var(--muted);
  font-family: var(--font-label);
  font-size: var(--type-label-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
  letter-spacing: 0;
}

.sp-quote-rule {
  width: 2px;
  flex: none;
  align-self: stretch;
  background: var(--grad-hairline);
}

.sp-quote-single-content {
  display: flex;
  flex-direction: column;
  gap: var(--space-250, 20px);
  max-width: 720px;
  margin: auto 0;
}

.sp-quote-single.is-wide-quote .sp-quote-single-content {
  max-width: 900px;
}

.sp-quote-single-row,
.sp-quote-lead-primary {
  display: flex;
  gap: 28px;
  /* The rule hangs outside the left margin so the quote itself lands on it,
     level with the kicker above. Derived from the rule width plus the gap, so it
     follows if either is retooled. */
  margin-left: calc(-1 * (2px + 28px));
}

.sp-quote-single-row > div,
.sp-quote-lead-primary > div {
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
}

/* Hero quote (slide 10). 22/32, not the old 26/36: the type pass emptied
   typography-overrides.css, which had been pinning this to ~20px, so it fell back
   to the component's 26 and came out LOUDER after a pass meant to quieten the
   deck. 22 is the hero tier — still clearly above the 18px card quotes on 13/25.
   --text-body rather than --ink: a quote is running sentence text, and reserving
   --ink for titles and statements is what keeps the hierarchy legible. */
.sp-quote-single-row p {
  margin: 0;
  color: var(--text-body);
  font-size: 22px;
  font-weight: var(--font-weight-regular);
  line-height: 32px;
  letter-spacing: var(--tracking-header);
  white-space: pre-line;
  text-wrap: balance;
}

.sp-quote-attribution {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.sp-quote-attribution span {
  font-size: 12px;
  font-weight: var(--font-weight-regular);
  line-height: 18px;
}

/* A row, not a stack: the mark sits beside the job title rather than under it,
   so the line reads "Data Engineering Manager  BLOCK". Only this variant — the
   lead / rail / tick attributions stay stacked. */
.sp-quote-attribution-single {
  flex-direction: row;
  align-items: center;
  gap: 14px;
}

/* 13/19 to match .sp-quote-attribution-lead — the two are the same role at the
   same tier and were a pixel apart for no reason. */
.sp-quote-attribution-single span {
  font-size: 13px;
  line-height: 19px;
}

/* Height comes from the per-logo inline style; width follows the aspect ratio. */
.sp-quote-logo {
  width: auto;
  display: block;
}

.sp-quote-attribution-lead span {
  font-size: 13px;
  line-height: 19px;
}

.sp-quote-role {
  color: var(--muted);
}

.sp-quote-company {
  color: var(--muted);
}

.sp-quote-split-grid {
  display: grid;
  flex: 1;
  min-height: 0;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: 56px;
  align-items: center;
}

.sp-quote-split-insight {
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
}

.sp-quote-split-insight h2 {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
  text-wrap: balance;
}

.sp-quote-split-insight > p {
  max-width: 440px;
  margin: 0;
  color: var(--text-secondary);
  font-size: 18px;
  font-weight: 300;
  line-height: 28px;
  text-wrap: pretty;
}

.sp-quote-split-tiles {
  display: flex;
  flex-direction: column;
  gap: var(--space-150);
}

.sp-quote-split-tile {
  display: flex;
  flex-direction: column;
  gap: var(--space-150);
  padding: var(--space-300) 28px;
  border: var(--border-accent) solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--paper);
}

.sp-quote-split-tile > p {
  margin: 0;
  color: var(--ink);
  font-size: 17px;
  font-weight: var(--font-weight-regular);
  line-height: 26px;
  text-wrap: pretty;
}

.sp-quote-split-attribution {
  display: flex;
  align-items: baseline;
  gap: var(--space-100);
  color: var(--muted);
}

.sp-quote-split-attribution span,
.sp-quote-split-attribution i {
  font-size: 12px;
  font-style: normal;
  font-weight: var(--font-weight-regular);
  line-height: 18px;
}

.sp-quote-split-attribution i {
  color: var(--muted);
}

.sp-quote-lead-grid {
  display: grid;
  flex: 1;
  min-height: 0;
  grid-template-columns: 1.25fr 1fr;
  gap: var(--space-800, 64px);
  align-items: center;
}

.sp-quote-lead-primary {
  gap: var(--space-300);
}

/* The multi-quote sibling of .sp-quote-single-row. It renders on no slide today,
   but it is the same hero tier, so it moves with it — otherwise the next slide to
   use the lead variant silently gets the old 26/36. */
.sp-quote-lead-primary p {
  margin: 0;
  color: var(--text-body);
  font-size: 22px;
  font-weight: var(--font-weight-regular);
  white-space: pre-line;
  line-height: 32px;
  text-wrap: balance;
}

.sp-quote-rail {
  display: flex;
  flex-direction: column;
  gap: var(--space-300);
}

.sp-quote-rail > div {
  display: flex;
  flex-direction: column;
  gap: var(--space-100);
  padding-bottom: var(--space-300);
  border-bottom: var(--border-thin) solid var(--hairline);
}

.sp-quote-rail > div:last-child {
  padding-bottom: 0;
  border-bottom: 0;
}

.sp-quote-rail p {
  margin: 0;
  color: var(--text-secondary);
  font-size: 16px;
  font-weight: var(--font-weight-regular);
  line-height: 24px;
  text-wrap: pretty;
}

.sp-quote-ticks-grid {
  display: grid;
  flex: 1;
  min-height: 0;
  grid-template-columns: repeat(var(--sp-quote-count), minmax(0, 1fr));
  gap: var(--space-600);
  align-content: center;
}

.sp-quote-bento .sp-frame-content {
  padding-top: var(--space-600);
  padding-bottom: var(--space-600);
}

.sp-quote-bento-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-150);
  margin-bottom: var(--space-300);
}

.sp-quote-bento-header h2 {
  max-width: 680px;
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
  text-wrap: balance;
}

.sp-quote-bento-grid {
  display: grid;
  flex: 1;
  min-height: 0;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr);
  grid-template-rows: auto auto;
  gap: var(--space-200);
  align-content: start;
}

.sp-quote-bento-card {
  display: flex;
  min-width: 0;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-200);
  padding: var(--space-300);
  border-radius: var(--radius-lg);
}

.sp-quote-bento-card > p,
.sp-quote-bento-card > span {
  margin: 0;
}

.sp-quote-bento-card > p {
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  text-wrap: pretty;
}

.sp-quote-bento-card > span {
  color: var(--muted);
  font-size: var(--type-label-size);
  font-weight: var(--font-weight-regular);
  line-height: 20px;
}

.sp-quote-bento-warm {
  background:
    radial-gradient(90% 120% at 100% 100%, rgba(242, 169, 196, 0.55), transparent 68%),
    radial-gradient(75% 90% at 0% 0%, rgba(214, 217, 252, 0.82), transparent 70%),
    var(--well);
}

.sp-quote-bento-neutral {
  background: var(--well);
}

.sp-quote-bento-count-3 .sp-quote-bento-card:nth-child(3) {
  grid-column: 1 / -1;
  align-self: start;
  justify-content: flex-start;
}

.sp-quote-bento-count-2 .sp-quote-bento-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: 1fr;
}

.sp-quote-tick-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
}

.sp-quote-tick-item > i {
  width: 40px;
  height: 2px;
  background: var(--grad-hairline);
}

.sp-quote-tick-item:nth-child(2) > i {
  background: linear-gradient(95deg, var(--grad-orchid), var(--grad-brand));
}

.sp-quote-tick-item:nth-child(3) > i {
  background: linear-gradient(95deg, var(--grad-brand), var(--grad-sky));
}

.sp-quote-tick-item p {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  text-wrap: pretty;
}

.sp-divider-copy {
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
  max-width: var(--content-narrow);
  margin-top: auto;
}

.sp-divider-copy h2,
.sp-ending-copy h2 {
  margin: 0;
  font-size: var(--type-divider-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-divider-line);
  letter-spacing: var(--tracking-divider);
  color: var(--paper);
  text-wrap: balance;
}

.sp-process-grid {
  display: grid;
  grid-template-columns: repeat(var(--sp-step-count), minmax(0, 1fr));
  gap: var(--space-400);
  margin-top: auto;
  margin-bottom: auto;
}

.sp-process-step {
  display: flex;
  flex-direction: column;
  gap: var(--space-150);
  min-width: 0;
}

.sp-process-number-row {
  display: flex;
  align-items: center;
  gap: var(--space-150);
}

.sp-process-number-row span {
  font-family: var(--font-label);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  background: var(--grad-type);
  background-clip: text;
  color: transparent;
}

/* Each numeral walks one step along the brand ramp rather than repeating a
   single gradient, so the strip reads as a progression. Mirrors the handoff's
   STEP_GRADS; five entries cover the primitive's 3-5 step range.
   background-image, not the `background` shorthand — the shorthand would reset
   the background-clip: text set above and paint solid blocks instead. */
.sp-process-step:nth-child(1) .sp-process-number-row span {
  background-image: linear-gradient(95deg, var(--grad-blue), var(--grad-orchid));
}

.sp-process-step:nth-child(2) .sp-process-number-row span {
  background-image: linear-gradient(95deg, var(--grad-orchid), var(--grad-brand));
}

.sp-process-step:nth-child(3) .sp-process-number-row span {
  background-image: linear-gradient(95deg, var(--grad-brand), var(--grad-sky));
}

.sp-process-step:nth-child(4) .sp-process-number-row span {
  background-image: linear-gradient(95deg, var(--grad-sky), var(--grad-rose));
}

.sp-process-step:nth-child(5) .sp-process-number-row span {
  background-image: linear-gradient(95deg, var(--grad-rose), var(--grad-orchid));
}

.sp-process-number-row i {
  flex: 1;
  height: var(--border-thin);
  background: var(--hairline);
}

.sp-process-step h3 {
  margin: 0;
  font-size: 18px;
  font-weight: var(--font-weight-semibold, 600);
  line-height: var(--type-body-line);
  color: var(--ink);
}

.sp-process-step p {
  margin: 0;
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
  color: var(--text-secondary);
}

.sp-workflow-strip .sp-header,
.sp-exploration .sp-header {
  margin-bottom: 0;
}

.sp-workflow-grid {
  display: grid;
  flex: 1;
  min-height: 0;
  grid-template-columns: repeat(var(--sp-workflow-count), minmax(0, 1fr));
  gap: var(--space-350);
  align-content: center;
}

.sp-workflow-stage {
  display: flex;
  flex-direction: column;
  gap: var(--space-150);
  min-width: 0;
}

.sp-workflow-label-row {
  display: flex;
  align-items: center;
  gap: var(--space-150);
}

.sp-workflow-label-row span,
.sp-workflow-label-row b {
  color: var(--muted);
  font-family: var(--font-label);
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
  white-space: nowrap;
}

.sp-workflow-label-row i {
  flex: 1;
  height: var(--border-thin);
  background: var(--hairline);
}

.sp-workflow-label-row b {
  margin-left: calc(var(--space-100) * -1);
}

.sp-workflow-stage > p {
  margin: 0;
  color: var(--text-secondary);
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
  text-wrap: pretty;
}

.sp-workflow-move .sp-workflow-label-row span {
  background: var(--grad-type);
  background-clip: text;
  color: transparent;
}

.sp-workflow-move > p {
  color: var(--ink);
}

.sp-exploration-content {
  display: flex;
  flex: 1;
  min-height: 0;
  flex-direction: column;
  justify-content: center;
}

.sp-exploration-grid {
  display: grid;
  grid-template-columns: repeat(var(--sp-exploration-count), minmax(0, 1fr));
  gap: var(--space-150);
}

.sp-exploration-option {
  display: flex;
  flex-direction: column;
  min-height: 300px;
  gap: var(--space-150);
  box-sizing: border-box;
  padding: var(--component-card-padding);
  border: var(--border-accent) solid transparent;
  border-radius: var(--radius-lg);
  background-image: linear-gradient(var(--paper), var(--paper)), var(--grad-rest);
  background-origin: border-box;
  background-clip: padding-box, border-box;
}

.sp-exploration-option:hover {
  background-image: linear-gradient(var(--paper), var(--paper)), var(--sp-exploration-border);
}

.sp-exploration-option-synthesis {
  min-height: 0;
}

.sp-exploration-icon {
  display: block;
  width: var(--space-300);
  height: var(--space-300);
  flex: none;
  background: var(--grad-type);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
}

.sp-exploration-icon-clay {
  display: block;
  width: var(--space-300);
  height: var(--space-300);
  flex: none;
  color: var(--blue);
  fill: currentColor;
}

.sp-exploration-icon-target {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='9' fill='none' stroke='black' stroke-width='2'/%3E%3Ccircle cx='12' cy='12' r='4.7' fill='none' stroke='black' stroke-width='2'/%3E%3Ccircle cx='12' cy='12' r='1.7' fill='black'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='9' fill='none' stroke='black' stroke-width='2'/%3E%3Ccircle cx='12' cy='12' r='4.7' fill='none' stroke='black' stroke-width='2'/%3E%3Ccircle cx='12' cy='12' r='1.7' fill='black'/%3E%3C/svg%3E");
}

.sp-exploration-icon-people {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='9' cy='8' r='3.6' fill='black'/%3E%3Cpath d='M2 19.6c0-3.9 3.1-6.3 7-6.3s7 2.4 7 6.3v.4H2z' fill='black'/%3E%3Ccircle cx='17.6' cy='9.2' r='2.9' fill='black'/%3E%3Cpath d='M16.6 14.6c3.1.3 5.4 2.4 5.4 5.1v.3h-4.5c0-2.1-.7-3.9-2.2-5.1.4-.2.8-.3 1.3-.3z' fill='black'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='9' cy='8' r='3.6' fill='black'/%3E%3Cpath d='M2 19.6c0-3.9 3.1-6.3 7-6.3s7 2.4 7 6.3v.4H2z' fill='black'/%3E%3Ccircle cx='17.6' cy='9.2' r='2.9' fill='black'/%3E%3Cpath d='M16.6 14.6c3.1.3 5.4 2.4 5.4 5.1v.3h-4.5c0-2.1-.7-3.9-2.2-5.1.4-.2.8-.3 1.3-.3z' fill='black'/%3E%3C/svg%3E");
}

.sp-exploration-icon-laptop {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Crect x='4.5' y='5' width='15' height='10' rx='1.6' fill='none' stroke='black' stroke-width='2'/%3E%3Cpath d='M2 17h20l-.7 2.1c-.2.5-.7.9-1.3.9H4c-.6 0-1.1-.4-1.3-.9z' fill='black'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Crect x='4.5' y='5' width='15' height='10' rx='1.6' fill='none' stroke='black' stroke-width='2'/%3E%3Cpath d='M2 17h20l-.7 2.1c-.2.5-.7.9-1.3.9H4c-.6 0-1.1-.4-1.3-.9z' fill='black'/%3E%3C/svg%3E");
}

.sp-exploration-option > span {
  width: fit-content;
  background: var(--grad-type);
  background-clip: text;
  color: transparent;
  font-family: var(--font-label);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
}

.sp-exploration-option h3,
.sp-exploration-option p {
  margin: 0;
  font-weight: var(--font-weight-regular);
}

.sp-exploration-option h3 {
  color: var(--ink);
  font-size: var(--type-card-title-size);
  line-height: var(--type-card-title-line);
}

.sp-exploration-option > p,
.sp-exploration-option > div p {
  color: var(--text-secondary);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
  text-wrap: pretty;
}

.sp-exploration-option > div {
  display: flex;
  flex-direction: column;
  gap: var(--space-100);
  margin-top: auto;
  padding-top: var(--space-200);
  border-top: var(--border-thin) solid var(--hairline);
}

.sp-exploration-option > div span {
  color: var(--muted);
  font-family: var(--font-label);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
}

.sp-exploration-connectors {
  display: block;
  width: 100%;
  height: 56px;
  margin-top: var(--space-150);
}

.sp-exploration-connectors path {
  fill: none;
  stroke: var(--hairline);
  stroke-width: var(--border-accent);
  vector-effect: non-scaling-stroke;
}

.sp-exploration-synthesis {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-100);
  max-width: 640px;
  margin: 0 auto;
  padding-top: var(--space-250);
  text-align: center;
}

.sp-exploration-synthesis > span {
  color: var(--muted);
  font-family: var(--font-label);
  font-size: var(--type-label-size);
  line-height: var(--type-body-line);
}

.sp-exploration-synthesis > p {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  text-wrap: balance;
}

.sp-principle-copy {
  display: flex;
  flex-direction: column;
  gap: var(--space-250, 20px);
  max-width: 720px;
  margin: auto 0;
}

.sp-principle-layout {
  display: grid;
  flex: 1;
  min-height: 0;
  grid-template-columns: minmax(0, 1fr) minmax(320px, 0.9fr);
  gap: 56px;
  align-items: stretch;
}

.sp-principle-layout .sp-principle-copy {
  max-width: none;
  margin: 0;
}

.sp-principle-visual {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-width: 0;
}

.sp-principle-copy > i {
  width: var(--space-600);
  height: var(--border-rule);
  background: var(--grad-hairline);
}

.sp-principle-statement {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-statement-size);
  font-weight: var(--font-weight-regular);
  /* One statement size means one leading, so the -h4 and -header variants
     follow this token too. --type-case-* now belongs to the case openers. */
  line-height: var(--type-statement-line);
  letter-spacing: var(--tracking-case);
  text-wrap: balance;
}

.sp-principle-statement-header {
  /* Only ai-hypothesis uses statementSize:"header", so this is scoped to that
     slide in practice. Dropped to the lead step — the sentence is a finding,
     not a headline, and at statement size it crowded the slide. */
  font-size: var(--type-lead-size);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
}

.sp-principle-statement-h4 {
  font-size: var(--type-statement-size);
  line-height: var(--type-statement-line);
  letter-spacing: var(--tracking-case);
}

/* 22px step. lineage-workflow-shift only — the pivot line runs on one row
   (statementParts.inline), and at statement size it would not fit. */
.sp-principle-statement-lead {
  font-size: 22px;
  line-height: 1.35;
}

.sp-principle-statement-inline {
  white-space: nowrap;
}

.sp-principle-statement-line {
  display: block;
  white-space: nowrap;
}

.sp-principle-copy > span {
  color: var(--text-secondary);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  text-wrap: pretty;
}

.sp-principle-copy > .sp-principle-support-inline {
  white-space: nowrap;
  text-wrap: nowrap;
}

.sp-principle-copy > .sp-principle-support-body {
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
}



.sp-principle-layout 











.sp-principle-chart {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.sp-principle-chart .axis,
.sp-principle-chart .marker {
  fill: none;
  stroke: var(--hairline);
  stroke-width: 1.5;
}

.sp-principle-chart .marker {
  stroke-dasharray: 4 6;
}

.sp-principle-chart .curve {
  fill: none;
  stroke: var(--blue);
  stroke-width: 3.5;
}

.sp-principle-chart text {
  fill: var(--text-secondary);
  font-family: var(--font-sans);
  font-size: 12px;
}

.sp-principle-chart .chart-peak {
  fill: var(--ink);
  font-size: 14px;
}

.sp-principle-chart .chart-trough {
  fill: #b45309;
}

.sp-principle-visual-note {
  width: fit-content;
  max-width: 100%;
  margin-top: var(--space-150);
  padding: var(--space-100) var(--space-150);
  border-radius: var(--radius-sm);
  background: var(--mock-chrome);
  color: var(--muted);
  font-size: var(--type-label-size);
  font-weight: var(--font-weight-regular);
  line-height: 20px;
}

/* ── Slide 31 · the diagnosis ──────────────────────────────────────────────
   Symmetric axis, and one step down from slide 30's 40px: 30 states the
   problem at full scale, 31 analyses it one level below. */
.sp-contrast-cards .sp-frame-content {
  padding: 64px 128px;
}

.sp-contrast-header {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.sp-contrast-header > p:not(.sp-kicker) {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin: 0;
  color: var(--ink);
  font-size: 20px;
  font-weight: var(--font-weight-regular);
  line-height: 28px;
  letter-spacing: -0.01em;
}

/* Authored line breaks, so the lines may not be nowrap — "Never whether they
   believed the answer." is longer than the old statement this slide carried. */
.sp-contrast-header > p > span {
  display: block;
}

.sp-contrast-header > p > span:last-child:not(:only-child) {
  background: var(--grad-type);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
}

.sp-contrast-grid {
  display: grid;
  flex: 1;
  min-height: 0;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-300);
  margin-top: 44px;
}

.sp-contrast-card {
  position: relative;
  display: flex;
  min-width: 0;
  overflow: hidden;
  flex-direction: column;
  justify-content: space-between;
  padding: 26px 30px;
  border-radius: 16px;
}

.sp-contrast-light {
  border: 1.5px solid var(--card-border);
  background: var(--paper);
}

.sp-contrast-dark {
  background: var(--night);
}

.sp-contrast-dark > i {
  position: absolute;
  inset: 0;
  filter: blur(18px);
  opacity: 0.85;
  background: var(--grad-divider);
  pointer-events: none;
}

.sp-contrast-card > div,
.sp-contrast-card > strong {
  position: relative;
}

.sp-contrast-card > div {
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
}

.sp-contrast-card > div > span {
  font-size: 12px;
  font-weight: var(--font-weight-regular);
  line-height: 18px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.sp-contrast-light > div > span {
  color: var(--muted);
}

.sp-contrast-dark > div > span {
  color: rgba(255, 255, 255, 0.58);
}

.sp-contrast-items {
  display: flex;
  flex-direction: column;
  gap: var(--space-125, 10px);
}

.sp-contrast-items > span {
  font-size: 15px;
  font-weight: var(--font-weight-regular);
  line-height: 22px;
  letter-spacing: normal;
  text-transform: none;
  color: var(--text-body);
}

.sp-contrast-dark .sp-contrast-items > span {
  color: rgba(255, 255, 255, 0.82);
}

/* Both words at one size. An earlier pass shrank "Silent." to 24px, which read
   as an unfinished card rather than as deliberate quiet — the opacity carries
   the meaning instead. */
.sp-contrast-card > strong {
  color: var(--ink);
  font-size: 40px;
  font-weight: var(--font-weight-regular);
  line-height: 44px;
  letter-spacing: -0.02em;
}

.sp-contrast-dark > strong {
  color: rgba(255, 255, 255, 0.42);
}

.sp-comparison-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-500);
  min-height: 0;
}

.sp-comparison-panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-100);
  min-width: 0;
  margin: 0;
}

.sp-shot-frame {
  padding: var(--space-100);
  border: var(--border-accent) solid var(--hairline);
  border-radius: var(--radius-md);
  background: var(--paper);
}

.sp-after .sp-shot-frame {
  border-color: transparent;
  background-image: linear-gradient(var(--paper), var(--paper)), var(--grad-hairline);
  background-origin: border-box;
  background-clip: padding-box, border-box;
}

.sp-after .sp-comparison-label {
  color: var(--blue);
}

.sp-shot-frame img {
  display: block;
  width: 100%;
  height: var(--shot-height);
  object-fit: cover;
  border-radius: var(--radius-sm);
}

.ds-image-placeholder {
  display: grid;
  width: 100%;
  height: 100%;
  min-height: var(--shot-height);
  place-content: center;
  gap: var(--space-100);
  box-sizing: border-box;
  border: var(--border-accent) dashed var(--panel-border);
  border-radius: var(--radius-sm);
  background:
    repeating-linear-gradient(
      -45deg,
      var(--paper),
      var(--paper) var(--placeholder-stripe),
      var(--well) var(--placeholder-stripe),
      var(--well) calc(var(--placeholder-stripe) * 2)
    );
  text-align: center;
  color: var(--muted);
}

.ds-image-placeholder span {
  font-family: var(--font-label);
  font-size: var(--type-label-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
  letter-spacing: 0;
  text-transform: none;
}

.ds-image-placeholder p {
  max-width: var(--content-narrow);
  margin: 0;
  padding: 0 var(--space-200);
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
}

.image-panel > .ds-image-placeholder,
.wire-reveal-trigger > .ds-image-placeholder,
.wire-overlay > .ds-image-placeholder {
  min-height: 100%;
}

.sp-comparison-panel figcaption {
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
  color: var(--muted);
}

.sp-showcase-grid {
  display: grid;
  grid-template-columns: var(--showcase-rail) minmax(0, 1fr);
  gap: var(--space-600);
  align-items: center;
  flex: 1;
  min-height: 0;
}

.sp-showcase-copy {
  display: flex;
  flex-direction: column;
  gap: var(--space-300);
}

.sp-showcase-copy .sp-header {
  margin-bottom: 0;
}

.sp-browser-frame {
  min-width: 0;
  padding: var(--mock-padding);
  border-radius: var(--radius-md);
  background: var(--mock-chrome);
}

.sp-browser-dots {
  display: flex;
  gap: 5px;
  padding: 0 2px var(--space-100);
}

.sp-browser-dots i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--panel-border);
}

.sp-browser-frame img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9.4;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background: var(--paper);
}

.slide.sp-ending-slide {
  background: var(--night);
  color: var(--paper);
}

.sp-ending-beam-ring,
.sp-ending-beam-dots {
  position: absolute;
  left: -45%;
  top: 18%;
  width: 230%;
  aspect-ratio: 1;
  border-radius: 50%;
  pointer-events: none;
}

.sp-ending-beam-ring {
  background: var(--grad-beam-ring);
  filter: blur(48px);
}

.sp-ending-beam-dots {
  background-image: radial-gradient(rgba(255, 255, 255, 0.55) 2px, transparent 2px);
  background-size: 18px 18px;
  -webkit-mask-image: radial-gradient(circle, transparent 50.5%, #000 52%, #000 55%, transparent 56.5%), linear-gradient(to left, #000 0%, transparent 45%);
  -webkit-mask-composite: source-in;
  mask-image: radial-gradient(circle, transparent 50.5%, #000 52%, #000 55%, transparent 56.5%), linear-gradient(to left, #000 0%, transparent 45%);
  mask-composite: intersect;
}

.sp-ending-copy {
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
  max-width: var(--content-case);
  margin: auto 0;
}

.sp-ending-copy > img {
  width: var(--space-400);
  height: var(--space-400);
  margin-bottom: var(--space-100);
}

/* One horizontal row of links separated by middots, not a stacked list — the
   contacts read as a signature line rather than a form. */
.sp-contact-list {
  display: flex;
  align-items: center;
  gap: 14px;
  align-self: flex-start;
  margin-top: var(--space-400);
}

.sp-contact-link {
  font-family: var(--font-label);
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
  letter-spacing: 0;
  text-transform: none;
  color: rgba(255, 255, 255, 0.88);
  text-decoration: none;
  cursor: pointer;
  /* The beam behind this is bright in places; the shadow keeps the link legible
     wherever it lands. */
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.45);
  transition: color 150ms ease;
}

.sp-contact-link:hover {
  color: #fff;
  text-decoration: underline;
  text-underline-offset: 4px;
}

.sp-contact-link:focus-visible {
  outline: 2px solid var(--paper);
  outline-offset: 3px;
  border-radius: 2px;
}

.sp-contact-sep {
  font-family: var(--font-label);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
  color: rgba(255, 255, 255, 0.35);
}

/* ContentsSlide — canonical numbered agenda with one washed gradient plane. */
.sp-contents-wash {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 52%;
  background: var(--grad-contents);
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 45%);
  mask-image: linear-gradient(to right, transparent 0%, #000 45%);
  pointer-events: none;
}

.sp-contents-wash.sp-contents-image {
  background-position: center;
  background-size: cover;
}

.sp-contents-dots {
  position: absolute;
  top: var(--space-700);
  right: var(--space-700);
  width: 180px;
  height: 260px;
  background-image: radial-gradient(rgba(83, 58, 253, 0.35) 1px, transparent 1px);
  background-size: var(--space-200) var(--space-200);
  -webkit-mask-image: linear-gradient(to bottom, #000, transparent);
  mask-image: linear-gradient(to bottom, #000, transparent);
}

.sp-contents-copy,
.sp-contents-list {
  display: flex;
  flex-direction: column;
}

.sp-contents-copy {
  gap: var(--space-400);
  margin: auto 0;
}

.sp-contents-list {
  /* 430 wrapped every entry. The copy column is 891px, so the cap was the
     only thing forcing two lines; 620 fits the longest row on one. */
  max-width: 620px;
  gap: var(--space-300);
}

.sp-contents-row {
  display: flex;
  align-items: baseline;
  gap: var(--space-300);
}

.sp-contents-row > span {
  flex: none;
  /* Fixed width so the rule and the item title share one x-axis down the list.
     The numerals are proportional in DM Sans — "01" measures 23.9px against
     "03" at 30.6px — which was stepping each row right by up to 7px. */
  width: 32px;
  font-variant-numeric: tabular-nums;
  background: var(--grad-type);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
  font-family: var(--font-label);
  /* Was var(--space-300). Same 24px, but a spacing token used as a type size
     means a change to the spacing scale silently resizes this text. */
  font-size: var(--type-header-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-header-line);
  letter-spacing: 0;
}

.sp-contents-row > i {
  flex: none;
  width: var(--space-300);
  height: var(--border-thin);
  background: var(--hairline);
}

.sp-contents-row > p {
  margin: 0;
  font-size: var(--type-lead-size);
  /* 400, matching the numeral above and slide 35's ledger rows. This was the
     one 500 on the slide; the agenda keeps its weight from the 24px numeral
     and the open row spacing, not from a heavier text face. */
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: 0;
  color: var(--ink);
  white-space: pre-line;
}

/* Shortlist — static ledger rows, no cards. */
.sp-shortlist .sp-frame-content {
  display: grid;
  grid-template-columns: 300px minmax(0, 1fr);
  gap: var(--space-600);
  align-items: center;
  padding: var(--space-600) 96px;
}

.sp-shortlist h2 {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
  text-wrap: balance;
}

.sp-shortlist-rows,
.sp-shortlist-row {
  display: flex;
}

.sp-shortlist-rows {
  flex-direction: column;
}

.sp-shortlist-row {
  align-items: center;
  gap: var(--space-300);
  padding: var(--space-200) 0;
  border-bottom: var(--border-thin) solid var(--hairline);
}

.sp-shortlist-row:last-child {
  border-bottom: 0;
}

.sp-shortlist-row > span {
  flex: none;
  min-width: var(--space-300);
  background: var(--grad-type);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
  font-size: var(--type-body-size);
}

.sp-shortlist-row > i {
  width: var(--space-300);
  height: var(--border-thin);
  flex: none;
  background: var(--hairline);
}

.sp-shortlist-row > p {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  line-height: var(--type-lead-line);
  text-wrap: pretty;
}

/* ShortlistReveal — a chosen ledger row opens its reasons without leaving the slide. */
.sp-shortlist-reveal .sp-frame-content {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: var(--space-600);
  align-items: center;
  padding: var(--space-600) 96px var(--space-600) var(--slide-inset-left);
}

.sp-shortlist-reveal-title h2,
.sp-shortlist-reveal-title p,
.sp-shortlist-reveal-reasons h3,
.sp-shortlist-reveal-reasons p {
  margin: 0;
}

.sp-shortlist-reveal-title h2 {
  margin-top: var(--space-150);
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
  text-wrap: balance;
}

.sp-shortlist-reveal-title h2 > span {
  display: block;
}

.sp-shortlist-reveal-title p {
  margin-top: var(--space-150);
  color: var(--muted);
  font-size: var(--type-label-size);
  line-height: var(--type-label-line);
}

.sp-shortlist-reveal-rows {
  display: flex;
  flex-direction: column;
}

.sp-shortlist-reveal-item {
  overflow: hidden;
  transition: max-height 280ms ease, opacity 180ms ease;
}

.sp-shortlist-reveal-item > button {
  position: relative;
  width: 100%;
  height: 53px;
  display: flex;
  align-items: center;
  gap: var(--space-300);
  padding: var(--space-150) 0;
  border: 0;
  border-bottom: var(--border-thin) solid var(--hairline);
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-align: left;
}

.sp-shortlist-reveal-item.is-selectable > button {
  cursor: pointer;
}

.sp-shortlist-reveal-item > button:disabled {
  cursor: default;
}

.sp-shortlist-reveal-item > button > b {
  min-width: var(--space-300);
  background: var(--grad-type);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
}

.sp-shortlist-reveal-item > button > i {
  width: var(--space-300);
  height: var(--border-thin);
  flex: none;
  background: var(--hairline);
}

.sp-shortlist-reveal-item.is-selectable > button > i {
  background: var(--grad-hairline);
}

.sp-shortlist-reveal-item > button > span {
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
}

.sp-shortlist-reveal-item > button > em {
  margin-left: auto;
  color: var(--muted);
  font-size: var(--type-label-size);
  font-style: normal;
  opacity: 0;
  transition: opacity 180ms ease;
}

.sp-shortlist-reveal-reasons {
  display: grid;
  gap: var(--space-150);
  max-height: 0;
  padding-top: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height 280ms ease, padding 280ms ease, opacity 180ms ease;
}

.sp-shortlist-reveal-reasons article {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  gap: var(--space-200);
  padding: var(--space-200) var(--space-250);
  border: var(--border-accent) solid transparent;
  border-radius: var(--radius-lg);
  background-image: linear-gradient(var(--paper), var(--paper)), var(--grad-hairline);
  background-clip: padding-box, border-box;
  background-origin: border-box;
}

/* Flat: this is inline emphasis inside a sentence, not an ordinal numeral.
   Bold plus ink is already enough emphasis. */
.sp-shortlist-reveal-reasons b {
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
}

.sp-shortlist-reveal-reasons h3 {
  color: var(--ink);
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
}

.sp-shortlist-reveal-reasons p {
  margin-top: var(--space-050);
  color: var(--text-secondary);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
}

.sp-shortlist-reveal.is-open .sp-shortlist-reveal-item:not(.is-selected) {
  max-height: 0;
  opacity: 0;
}

.sp-shortlist-reveal.is-open .sp-shortlist-reveal-item.is-selected > button {
  border-bottom-color: transparent;
}

.sp-shortlist-reveal.is-open .sp-shortlist-reveal-item.is-selected > button::after {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 2px;
  background: var(--grad-hairline);
  content: "";
}

.sp-shortlist-reveal.is-open .sp-shortlist-reveal-item.is-selected > button > em {
  opacity: 1;
}

.sp-shortlist-reveal.is-open .sp-shortlist-reveal-item.is-selected .sp-shortlist-reveal-reasons {
  max-height: 360px;
  padding-top: var(--space-300);
  opacity: 1;
}

/* GlassMoves — buildable, glass cards inside the shared aurora panel. */
.sp-glass-moves {
  cursor: pointer;
}

.sp-glass-moves .sp-frame-content {
  padding: var(--space-600) 96px var(--space-600) var(--slide-inset-left);
}

.sp-glass-moves header h2 {
  margin: var(--space-150) 0 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
}

.sp-glass-moves-panel {
  position: absolute;
  /* 104 horizontal so the panel's 24px padding lands the cards on the 128 axis
     and the glass bleeds 24 outside it on each side. */
  inset: 150px 104px 24px;
  display: grid;
  grid-template-columns: repeat(var(--sp-glass-move-count), minmax(0, 1fr));
  gap: var(--space-200);
  /* Centre the row as a group, but keep the cards the same height: centring
     them individually left a card whose title wrapped to two lines taller than
     its neighbours, with its rule on a different y. */
  align-content: center;
  align-items: stretch;
  box-sizing: border-box;
  padding: var(--space-300);
  overflow: hidden;
  border-radius: var(--radius-panel);
  background: var(--grad-aurora-panel);
}

.sp-glass-moves-panel article {
  display: flex;
  flex-direction: column;
  /* Rule, number, title and description as one stack — the 38x38 badge and a
     48px gap read as two unrelated objects. Same anatomy as
     .sp-hypothesis-card. The description sets the height now. */
  gap: var(--space-100);
  min-height: 0;
  padding: var(--space-300);
  border: var(--border-thin) solid var(--glass-border);
  border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--paper) 42%, transparent);
  box-shadow: var(--elevation-1);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  transition: opacity 280ms ease, transform 280ms cubic-bezier(.4, 0, .2, 1);
}

/* Thin gradient rule above the number, matching .sp-hypothesis-bar. */
.sp-glass-moves-panel article::before {
  content: "";
  width: 32px;
  height: 2px;
  border-radius: var(--radius-pill);
  background: var(--grad-type);
}

/* Badge reduced to a plain gradient-clipped numeral, matching
   .sp-hypothesis-num. The gradient text clip is unchanged. */
.sp-glass-moves-panel article > b {
  display: block;
  width: auto;
  height: auto;
  place-items: initial;
  border: 0;
  border-radius: 0;
  background: var(--grad-type);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
  font-family: var(--font-mono, var(--font-label));
  font-size: 18px;
  line-height: 26px;
  font-weight: var(--font-weight-medium, 500);
}

.sp-glass-moves-panel article > p {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-medium, 500);
  line-height: var(--type-lead-line);
}

.sp-glass-move-desc {
  color: var(--muted);
  font-size: var(--type-label-size);
  line-height: 20px;
}

.sp-glass-moves[data-glass-build="0"] article,
.sp-glass-moves[data-glass-build="1"] article:nth-child(n + 2),
.sp-glass-moves[data-glass-build="2"] article:nth-child(n + 3) {
  opacity: 0;
  transform: translateY(10px);
}

/* BentoGrid — one filled gradient hero tile, supporting paper tiles. */
.slide.sp-bento-grid {
  background: var(--well);
}

.sp-bento-grid .sp-frame-content {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  grid-template-rows: auto 1fr 1fr;
  gap: var(--space-150);
  padding: var(--space-700) 96px;
}

.sp-bento-kicker {
  grid-column: 1 / -1;
}

.sp-bento-hero,
.sp-bento-stat,
.sp-bento-action {
  box-sizing: border-box;
  border-radius: var(--radius-lg);
}

.sp-bento-hero {
  display: flex;
  grid-row: 2 / 4;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--space-100);
  padding: var(--space-400);
  background: var(--grad-hover);
  color: var(--paper);
}

.sp-bento-hero strong {
  font-size: var(--type-stat-multi-size);
  font-weight: 600;
  line-height: 1;
}

.sp-bento-hero h3,
.sp-bento-action h3,
.sp-bento-stat p,
.sp-bento-hero p,
.sp-bento-action p {
  margin: 0;
}

.sp-bento-hero h3 {
  font-size: var(--type-lead-size);
  line-height: 26px;
}

.sp-bento-hero p,
.sp-bento-action p {
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
}

.sp-bento-hero p {
  color: var(--white-82);
}

.sp-bento-stat {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--space-100);
  padding: var(--space-300);
  border: var(--border-accent) solid transparent;
  background-image: linear-gradient(var(--paper), var(--paper)), var(--grad-hairline);
  background-clip: padding-box, border-box;
  background-origin: border-box;
}

.sp-bento-stat strong {
  color: var(--accent);
  font-size: 36px;
  line-height: 1;
}

.sp-bento-stat p {
  color: var(--ink);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
}

.sp-bento-action {
  display: flex;
  grid-column: 2 / 4;
  align-items: center;
  gap: var(--space-250);
  padding: var(--space-250) var(--space-300);
  border: var(--border-thin) solid var(--hairline);
  background: radial-gradient(60% 120% at 100% 100%, rgba(214, 217, 252, 0.9), transparent 70%), var(--paper);
}

.sp-bento-action > span {
  display: grid;
  width: var(--space-600);
  height: var(--space-600);
  flex: none;
  place-items: center;
  border-radius: var(--radius-pill);
  background: var(--grad-type);
  color: var(--paper);
  font-size: var(--type-card-title-size);
}

.sp-bento-action h3 {
  color: var(--ink);
  font-size: var(--type-card-title-size);
}

.sp-bento-action p {
  color: var(--muted);
}

/* Shared design-system components used inside primitives and legacy slides. */
.ds-quote-card,
.ds-principle-card,
.ds-agenda-item,
.ds-model-layer,
.ds-bento-card,
.ds-process-card {
  position: relative;
  box-sizing: border-box;
  border: var(--border-accent) solid var(--hairline);
  border-radius: var(--radius-md);
  background: var(--paper);
}

.ds-quote-card::before,
.ds-principle-card::before,
.ds-model-layer::before {
  content: "";
  position: absolute;
  inset: -1.5px -1.5px auto;
  height: 3px;
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  background: var(--grad-hairline);
}

.ds-role-row,
.ds-detail-row {
  font-weight: var(--font-weight-regular);
}

.ds-quote-card p,
.ds-principle-card p,
.ds-agenda-item p,
.ds-model-layer p,
.ds-role-row strong,
.ds-detail-row p {
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
}

.ds-bento-card {
  transition: transform 800ms cubic-bezier(0.165, 0.84, 0.44, 1), border-color 800ms cubic-bezier(0.165, 0.84, 0.44, 1);
}

.ds-bento-card:hover,
.ds-bento-card:focus-within {
  transform: translateY(-4px);
  border-color: var(--accent);
}

.slide.ds-agent-landscape {
  display: grid;
  grid-template-columns: 0.32fr 0.68fr;
  gap: var(--space-400);
  align-items: center;
  padding: var(--slide-y) var(--slide-x);
}

.ds-agent-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-200);
}

.ds-agent-grid .agenda-item {
  min-height: 150px;
  padding: var(--component-card-padding);
}

.slide .career-brand {
  font-weight: var(--font-weight-regular);
}

/* StepSpotlight — numbered step list left, one live-demo panel right on an aurora panel. */
.sp-step-spotlight .sp-frame-content {
  display: flex;
  padding: var(--space-700) var(--space-600) var(--space-700) var(--slide-inset-left);
}

.sp-step-spotlight-media {
  position: absolute;
  top: var(--space-300);
  right: var(--space-300);
  bottom: var(--space-300);
  left: var(--slide-media-left);
  background: var(--grad-aurora-panel);
  border-radius: var(--radius-xl);
  overflow: hidden;
}

.sp-step-spotlight-stage {
  position: absolute;
  inset: var(--space-300);
  display: flex;
  align-items: center;
  justify-content: center;
}

.sp-step-spotlight-box {
  position: relative;
  max-width: 100%;
  max-height: 100%;
  overflow: hidden;
}

.sp-step-spotlight-box.is-framed {
  border-radius: var(--radius-lg);
  background: var(--paper);
  box-shadow: var(--elevation-1);
}

.sp-step-spotlight-canvas {
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: top left;
}

.sp-step-spotlight-canvas > iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

.sp-step-spotlight-media .sp-compare-toggle {
  bottom: var(--space-150);
}

.sp-step-spotlight-copy {
  position: relative;
  z-index: 1;
  width: var(--slide-copy-width);
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-200);
}

.sp-step-spotlight-copy h2 {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
  text-wrap: balance;
}

.sp-step-spotlight-copy p {
  margin: 0;
  color: var(--text-secondary);
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
}

.sp-step-spotlight-copy p .sp-accent-bold {
  color: var(--accent);
  font-weight: var(--font-weight-medium, 600);
}

.sp-step-spotlight-steps {
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
  margin-top: var(--space-250);
}

.sp-step-spotlight-step {
  all: unset;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: var(--space-150);
}

.sp-step-spotlight-num {
  /* Fixed width so the step titles share one x-axis. DM Sans numerals are
     proportional — "01" measured 15px against "04" at 18.9px — which was
     stepping each title right by up to 4px. */
  flex: none;
  width: 20px;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-label);
  font-size: var(--type-control-size);
  font-weight: var(--font-weight-regular);
  letter-spacing: 0.08em;
  color: var(--muted);
}

.sp-step-spotlight-step.active .sp-step-spotlight-num {
  background: var(--grad-type);
  background-clip: text;
  color: transparent;
}

/* Inactive state. --ink lives on .active — do not promote this. */
.sp-step-spotlight-step-title {
  font-size: var(--type-card-title-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-card-title-line);
  color: var(--text-secondary);
  transition: color var(--motion-base) var(--ease-out);
}

.sp-step-spotlight-step.active .sp-step-spotlight-step-title {
  font-weight: var(--font-weight-medium, 500);
  color: var(--ink);
}

.sp-step-spotlight-chip {
  display: block;
  width: fit-content;
  margin: calc(-1 * var(--space-075)) 0 0 calc(13px + var(--space-150));
  padding: var(--space-075) var(--space-150);
  border: var(--border-thin) solid var(--hairline);
  border-radius: var(--radius-sm);
  background: var(--glass-fill-soft);
  box-shadow: var(--elevation-subtle);
  font-family: var(--font-label);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--text-secondary);
  white-space: nowrap;
}

/* Title emphasis — **bold** spans in headline text, three treatments. */
.sp-emph-text {
  color: var(--emph-text);
  font-weight: var(--font-weight-medium, 600);
}

.sp-emph-wash {
  background: var(--emph-wash-bg);
  border-radius: var(--radius-xs);
  padding: 0 var(--space-050);
  margin: 0 -1px;
  color: var(--emph-wash-text);
}

.sp-emph-underline {
  text-decoration-line: underline;
  text-decoration-color: var(--emph-underline);
  text-decoration-thickness: 3px;
  text-underline-offset: 4px;
}

.sp-title-line {
  display: block;
  white-space: nowrap;
}

/* ScreenShowcase — decision list shared by both static and demo modes. */
.sp-showcase-decisions {
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
}

.sp-showcase-decision {
  display: flex;
  gap: var(--space-150);
  align-items: flex-start;
}

.sp-showcase-decision-num {
  flex: none;
  /* Fixed width so every title starts on the same x-axis: the numerals are
     proportional in DM Sans, where "01" is 18.3px against "03" at 23.1px, which
     was staggering the titles by ~5px. Tabular figures keep the digits even. */
  width: 24px;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono, var(--font-label));
  font-size: 18px;
  font-weight: var(--font-weight-medium, 500);
  line-height: 26px;
  background: var(--grad-type);
  background-clip: text;
  color: transparent;
}

.sp-showcase-decision-copy {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-top: 2px;
}

.sp-showcase-decision-title {
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-medium, 600);
  color: var(--ink);
}

.sp-showcase-decision-text {
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
  color: var(--text-secondary);
}

/* Sub-text only where a decision has a title above it. Scoped by sibling on
   purpose: lineage-discovery-showcase also uses `decisions`, but with bare
   labels and no titles, and an unscoped rule would quietly restyle it too. */
.sp-showcase-decision-title ~ .sp-showcase-decision-text {
  font-size: 13.5px;
  line-height: 18px;
  color: var(--muted);
}

.sp-showcase-decision-text b {
  color: var(--ink);
  font-weight: var(--font-weight-medium, 500);
}

.sp-showcase-footnote {
  margin: 0;
  color: var(--muted);
  font-size: var(--type-control-size);
  line-height: var(--type-control-line);
  text-wrap: pretty;
}

/* ScreenShowcase demo mode — live iframe(s) on an aurora panel behind frosted glass chrome. */
.sp-screen-showcase-demo .sp-frame-content {
  display: flex;
  padding: var(--space-700) var(--space-600) var(--space-700) var(--slide-inset-left);
}

.sp-showcase-demo-copy {
  position: relative;
  z-index: 1;
  width: var(--slide-copy-width);
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-300);
}

.sp-showcase-demo-copy h2 {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  letter-spacing: var(--tracking-body);
  line-height: var(--type-lead-line);
  text-wrap: balance;
}

.sp-screen-showcase-demo.is-compact-title .sp-showcase-demo-copy h2 {
  font-size: var(--type-h3-size);
  line-height: var(--type-h3-line);
  letter-spacing: 0;
}

.sp-showcase-demo-media {
  position: absolute;
  top: var(--space-300);
  right: var(--space-300);
  bottom: var(--space-300);
  left: var(--slide-media-left);
  border-radius: var(--radius-xl);
  background: var(--grad-aurora-panel);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-300);
  box-sizing: border-box;
}

.sp-showcase-demo-glass {
  width: 100%;
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, 0.42);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  backdrop-filter: blur(18px) saturate(150%);
  border: var(--border-thin) solid rgba(255, 255, 255, 0.85);
  box-shadow: var(--elevation-1);
  padding: var(--space-100);
  box-sizing: border-box;
}

.sp-showcase-demo-dots {
  display: flex;
  gap: var(--space-100);
  padding: 2px var(--space-100) var(--space-100);
}

.sp-showcase-demo-dots i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(13, 37, 61, 0.22);
}

.sp-showcase-demo-media .sp-compare-toggle {
  bottom: var(--space-150);
}

/* ---------- Learned slide ---------- */

/* One column now: text on top, the two cards as a 2-up grid beneath it. The
   padding was already the design's inset (64 / 96 / 64 / 128), so only the axis
   changed. Cards used to sit in a right-hand column beside the statement. */
.sp-learned-slide .sp-frame-content {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 36px;
  padding: var(--space-700) 96px var(--space-700) var(--slide-inset-left);
}

/* 450, not the copy column's 400: "The problem wasn't how to render more
   lineage." measures 442px at 20px, so at 380 it wrapped and the sentence read
   as two. The h2 deliberately overhangs its grid track into the 72px column gap
   — the track and .sp-learned-cards stay exactly where they are, so the two
   quote cards do not narrow and the second one cannot be pushed off the stage.
   Right edge lands at 578 against the cards' 600.

   text-wrap is pretty, not balance: balance evens line lengths across the block
   and would happily re-break the first sentence in two to match the second. */
.sp-learned-copy h2 {
  /* width, not max-width: the copy column is a fixed 400px grid track, so a
     max-width above 400 is simply never reached — the box still measures 400 and
     the sentence still wraps. An explicit width is what makes it overhang. */
  max-width: 700px;
  margin: var(--space-150) 0 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
  text-wrap: pretty;
}

/* Two classes — `.slide.sp-slide` also sets `background`, so a single-class rule
   loses on specificity and the wash silently disappears. Same --grad-wash token
   slides 13 and 25 use, referenced rather than re-declared. */
.slide.sp-learned-slide {
  background: var(--grad-wash);
}

.sp-learned-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-250);
}

/* Same card language as slides 13 and 25: 1px hairline, 12px radius, even 24px
   padding, the subtle elevation, 16px inner gap. .sp-learned-bar was deleted with
   this — a purely decorative gradient rule would have made 18 the one quote slide
   with its own grammar, where 13 uses that slot for its semantic ordinals and 25
   leaves it empty. */
.sp-learned-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
  padding: 28px;
  border-radius: var(--radius-lg);
  background: var(--paper);
  border: var(--border-thin) solid var(--card-border);
  box-shadow: var(--elevation-subtle);
}

.sp-learned-quote {
  margin: 0;
  color: var(--text-body);
  font-size: var(--type-card-title-size);
  font-weight: var(--font-weight-regular);
  line-height: 26px;
  letter-spacing: var(--tracking-body);
  text-wrap: balance;
}

/* Explicit --ink: the quote itself is --text-body now, so the emphasised span
   would otherwise inherit body colour and lose its lift. */
.sp-learned-quote b {
  color: var(--ink);
  font-weight: var(--font-weight-medium, 500);
}

/* Divider above the attribution, full card width inside the padding. No dot
   between role and logo — 13 and 25 had theirs removed, and 18 follows them. */
/* margin-top: auto pins this to the card's bottom, so the two dividers land on
   one line even though the quotes differ in length — the same job flex: 1 does
   on the quote in slide 25's cards. */
.sp-learned-attribution {
  margin: auto 0 0;
  display: flex;
  align-items: baseline;
  gap: var(--space-125, 10px);
  padding-top: 16px;
  border-top: var(--border-thin) solid var(--card-border);
}

.sp-learned-role {
  color: var(--muted);
  font-size: 13px;
  font-weight: var(--font-weight-regular);
  line-height: 19px;
}

/* Height from the per-logo inline style the logo pass tuned; width follows.
   align-self: center because the row is baseline-aligned for the role text —
   an image has no baseline of its own and would otherwise sit on the row's. */
.sp-learned-logo {
  flex: none;
  width: auto;
  max-width: 110px;
  object-fit: contain;
  display: block;
  align-self: center;
}

/* ---------- Load Time slide ---------- */

/* The copy column has to clear the headline's longest line and the stat column
   has to clear the numeral, out of 848px of content — hence the explicit split
   rather than letting either side size itself. */
.sp-loadtime-slide .sp-frame-content {
  display: flex;
  flex-direction: column;
  /* Symmetric on the axis so the panel's -24px bleed resolves to 104 / 936 and
     its own 24px padding puts the eyebrow, the stats and the caption back on
     128. The right edge was still 48 from before the axis pass. */
  padding: 44px var(--slide-inset-left) 24px var(--slide-inset-left);
}

.sp-loadtime-copy {
  display: flex;
  flex-direction: column;
  gap: var(--space-125, 10px);
}

/* Class path kept from the previous layout on purpose: a saved typography
   override in typography-overrides.css targets exactly
   .sp-loadtime-copy > h2, and renaming it would silently drop that edit. */
.sp-loadtime-copy h2 {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
  text-wrap: pretty;
}

/* Full-bleed panel; same radial stack as .sp-hypothesis-panel and
   .sp-strength-media so the glass slides stay one family. */
.sp-loadtime-panel {
  flex: 1;
  min-height: 0;
  margin: 26px -24px 0;
  padding: var(--space-300);
  box-sizing: border-box;
  border-radius: var(--radius-xl);
  overflow: hidden;
  display: flex;
  background:
    radial-gradient(60% 50% at 18% 8%, rgba(102, 94, 253, 0.34), transparent 60%),
    radial-gradient(50% 40% at 88% 28%, rgba(242, 169, 196, 0.38), transparent 65%),
    radial-gradient(55% 45% at 55% 95%, rgba(110, 195, 240, 0.38), transparent 60%),
    linear-gradient(160deg, #edeffb, #f6f1fa);
}

/* The stats used to start invisible and wait for a click, which left the slide
   as a blank gradient panel with no hint that anything was there. The resting
   state is now visible and the entrance is a keyframe animation — animations run
   on insertion with no class flip, so nothing here depends on JS, on a class, or
   on an animation frame that may never arrive. If the animation is skipped
   entirely, the cards are already on screen. */
.sp-loadtime-reveal {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
  animation: sp-loadtime-reveal-in 1.4s cubic-bezier(0.22, 1, 0.36, 1);
}

@keyframes sp-loadtime-reveal-in {
  from {
    opacity: 0;
    filter: blur(10px);
    transform: scale(1.06);
  }
}

@media (prefers-reduced-motion: reduce) {
  .sp-loadtime-reveal {
    animation: none;
  }
}

.sp-loadtime-stats {
  flex: 1;
  min-height: 0;
  display: flex;
  gap: var(--space-200);
  align-items: stretch;
}

/* Same glass recipe as .sp-hypothesis-card. */
.sp-loadtime-card {
  box-sizing: border-box;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.42);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  border: 1px solid rgba(255, 255, 255, 0.85);
  box-shadow: var(--elevation-1);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.sp-loadtime-primary {
  flex: 1.6;
  align-items: flex-start;
  gap: var(--space-150);
  padding: 30px 40px;
}

.sp-loadtime-side {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
}

.sp-loadtime-side-card {
  flex: 1;
  gap: var(--space-100);
  padding: 20px 28px;
}

.sp-loadtime-card-label {
  color: var(--stat-neutral);
  font-size: 12px;
  font-weight: var(--font-weight-semibold, 600);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.sp-loadtime-number {
  font-size: 104px;
  font-weight: var(--font-weight-regular);
  line-height: 1;
  letter-spacing: -0.03em;
  padding-right: 0.04em;
  margin-right: -0.04em;
  background: var(--grad-stat-problem);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
}

.sp-loadtime-side-value {
  color: var(--ink);
  font-size: 36px;
  font-weight: var(--font-weight-regular);
  line-height: 1;
  letter-spacing: -0.02em;
}

/* The second reads as the quieter of the pair in the handoff. */
.sp-loadtime-side-card:last-child .sp-loadtime-side-value {
  color: var(--muted);
  font-size: 28px;
  letter-spacing: -0.01em;
}

.sp-loadtime-note {
  margin: 0;
  color: var(--muted);
  font-size: 14px;
  line-height: 20px;
  text-wrap: pretty;
}

/* ---------- Hypothesis slide ---------- */

.sp-hypothesis-slide .sp-frame-content {
  display: flex;
  flex-direction: column;
  gap: var(--space-500);
  cursor: pointer;
}

/* Two classes on purpose: `.slide h2` in styles.css is (0,1,1) and would
   otherwise win over a single-class selector on the same h2, which is why
   this title needed a per-slide override before. */
.sp-hypothesis-slide .sp-hypothesis-title {
  max-width: 760px;
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
  text-wrap: balance;
}

.sp-hypothesis-panel {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-200);
  /* Bleed 24 outside the content box so the panel's own 24px padding lands its
     cards back on the 128 axis. align-items: center stays — the connector SVG
     and the synthesis pill are meant to be centred; only the grid stretches. */
  margin: 0 -24px;
  padding: var(--space-300);
  border-radius: var(--radius-xl);
  background:
    radial-gradient(60% 50% at 18% 8%, rgba(102, 94, 253, 0.34), transparent 60%),
    radial-gradient(50% 40% at 88% 28%, rgba(242, 169, 196, 0.38), transparent 65%),
    radial-gradient(55% 45% at 50% 110%, rgba(110, 195, 240, 0.35), transparent 62%),
    #f6f5fc;
}

.sp-hypothesis-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 240px));
  gap: var(--space-200);
  /* The panel centres its children, so this box was shrinking to its content
     (3 x 240 + 2 x 16 = 752) and centring itself 16px off the axis. The tracks
     are capped at 240 either way, so stretching moves the cards without
     widening them. */
  align-self: stretch;
}

.sp-hypothesis-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-100);
  padding: var(--space-300);
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, 0.42);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  border: 1px solid rgba(255, 255, 255, 0.85);
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.4s ease, transform 0.4s ease;
}

.sp-hypothesis-card.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.sp-hypothesis-bar {
  width: 32px;
  height: 2px;
  border-radius: var(--radius-pill);
}

.sp-hypothesis-num {
  font-family: var(--font-mono, var(--font-label));
  font-size: 18px;
  font-weight: var(--font-weight-medium, 500);
  line-height: 26px;
  background-clip: text;
  color: transparent;
}

.sp-hypothesis-name {
  color: var(--ink);
  font-size: var(--type-label-size);
  font-weight: var(--font-weight-medium, 500);
}

.sp-hypothesis-desc {
  color: var(--muted);
  font-size: var(--type-label-size);
  line-height: 20px;
}

.sp-hypothesis-lines {
  width: 300px;
  height: 64px;
}

.sp-hypothesis-lines-spacer {
  height: 64px;
}

.sp-hypothesis-line {
  fill: none;
  stroke: var(--grad-blue);
  stroke-width: 1.5;
  opacity: 0.45;
}

.sp-hypothesis-synthesis {
  padding: var(--space-200) var(--space-300);
  border-radius: var(--radius-pill);
  background: var(--grad-type);
  /* Was var(--white-92, #fff) — --white-92 was never defined anywhere, so this
     always rendered the fallback. --paper is the deck's white, and this pill sits
     on the saturated --grad-type, where full-strength white is what's wanted. */
  color: var(--paper);
  font-size: var(--type-label-size);
  font-weight: var(--font-weight-medium, 500);
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity 0.4s ease, transform 0.4s ease;
}

.sp-hypothesis-synthesis.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* ---------- Redesign Overview slide ---------- */

.sp-redesign-overview-slide .sp-frame-content {
  display: flex;
  flex-direction: column;
  gap: var(--space-150);
  /* 24, like every other gutter in the deck; this was the one object sitting in
     a 20. Keep in step with the title's offset below. */
  padding: var(--space-300);
  cursor: pointer;
}

/* Two classes on purpose: `.slide h2` in styles.css is (0,1,1) and would
   otherwise win over a single-class selector on the same h2, which is why
   this title needed a per-slide override before. */
.sp-redesign-overview-slide .sp-redesign-title {
  /* The axis goes on the title alone. This wrapper also holds the browser mock,
     so insetting the wrapper pushed the mock 88px off the right of the stage.
     Subtracts the wrapper's own padding, so it tracks --space-300 above. */
  margin: 0 0 0 calc(var(--slide-inset-left) - var(--space-300));
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-medium, 500);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
}

.sp-redesign-browser {
  position: relative;
  flex: 1;
  min-height: 0;
  /* Hairline on all four sides, like every other framed mock in the deck (see
     .sp-option-reveal-demo-media). Without it the white chrome bar sat on the
     near-white slide with nothing drawing its top edge, so the mock read as
     though it had been cut off above the bar. */
  border: var(--border-thin) solid var(--hairline);
  border-radius: var(--radius-lg);
  box-sizing: border-box;
  background: var(--well);
  overflow: hidden;
}

.sp-redesign-browser-bar {
  display: flex;
  align-items: center;
  gap: var(--space-200);
  height: 38px;
  padding: 0 var(--space-200);
  background: #fff;
  border-bottom: 1px solid rgba(13, 37, 61, 0.08);
}

.sp-redesign-dots-os {
  display: flex;
  gap: 6px;
}

.sp-redesign-dots-os i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(13, 37, 61, 0.16);
}

.sp-redesign-url {
  padding: 4px var(--space-150);
  border-radius: var(--radius-sm);
  background: rgba(13, 37, 61, 0.05);
  color: var(--muted);
  font-size: 11px;
}

.sp-redesign-canvas {
  position: relative;
  width: 1000px;
  height: 469px;
  margin: 0 auto;
  overflow: hidden;
}

.sp-redesign-canvas img {
  position: absolute;
  top: -30px;
  left: 0;
  width: 1000px;
  height: auto;
  display: block;
}

.sp-redesign-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.sp-redesign-line {
  stroke: var(--grad-blue);
  stroke-width: 1.5;
  opacity: 0.6;
}

.sp-redesign-target {
  position: absolute;
  width: 10px;
  height: 10px;
  transform: translate(-50%, -50%);
}

.sp-redesign-ping {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  opacity: 0.55;
  animation: sp-redesign-ping-anim 1.8s ease-out infinite;
}

.sp-redesign-ping-delay {
  animation-delay: 0.9s;
}

.sp-redesign-dotmark {
  position: absolute;
  inset: 2.5px;
  border-radius: 50%;
  /* Not elevation — a ring / knockout outline, drawn with a 0-blur spread. */
  box-shadow: 0 0 0 2px #fff;
}

@keyframes sp-redesign-ping-anim {
  0% { transform: scale(0.6); opacity: 0.55; }
  100% { transform: scale(2.6); opacity: 0; }
}

.sp-redesign-card {
  position: absolute;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: var(--space-150);
  border-radius: var(--radius-md);
  background: #fff;
  box-shadow: var(--elevation-card);
  animation: sp-redesign-card-in 0.35s ease both;
}

@keyframes sp-redesign-card-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

.sp-redesign-card-title {
  font-size: 12px;
  font-weight: var(--font-weight-medium, 500);
  color: var(--ink);
  width: max-content;
}

.sp-redesign-card-item {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-size: 11px;
  line-height: 16px;
}

.sp-redesign-card-item i {
  flex: none;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--muted);
}

.sp-redesign-footer {
  display: flex;
  align-items: center;
  gap: var(--space-150);
}

.sp-redesign-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(13, 37, 61, 0.16);
  transition: background 0.3s ease;
}

.sp-redesign-dot.is-on {
  background: var(--grad-blue);
}

.sp-redesign-hint {
  color: var(--muted);
  font-size: 11px;
}

/* ---------- Testimonial quote cards (slide 25) ----------

   One row of three cards. The first is wider than the other two and sits
   left-most — that width IS the hierarchy, which is why all three quotes are the
   same size. Its quote ("without loading the whole universe") answers slide 13's
   "not the whole universe", so it has to read first.

   No ordinals here: 01/02 on slide 13 deliver the two jobs its lead sentence
   promises. These are three peer testimonials promising no such sequence.

   Deleted in this pass, all dead once slide 13 moved to .sp-quote-numbered-*:
   the decorative quote mark and its three tone variants, the inner figure wrapper
   and its faux gradient border, the brand-glow hover that depended on that border,
   the bento grid, and every .sp-quote-testimonial-2up rule (no slide emitted it). */

/* Two classes — `.slide.sp-slide` also sets `background`, so a single-class rule
   loses on specificity and the wash silently disappears. Same --grad-wash token
   slide 13 uses; the two slides declare it separately because they share no
   wrapper class. */
.slide.sp-quote-testimonial {
  background: var(--grad-wash);
}

/* No .sp-frame-content override: its default padding is already
   var(--slide-y) var(--slide-x) = 96 / 128, which puts the eyebrow at y 96 (the
   same rhythm as slide 20) and runs the row from 128 to 912 — the right edge 14
   other text slides use. The spec asked for 104-128px of right margin; 128 is the
   deck's own value inside that range, so no new number was invented. */

.sp-quote-testimonial-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-150);
}

.sp-quote-testimonial-header h2 {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
  text-wrap: balance;
}

/* 1.6 : 1 : 1 as fr units, so the ratio is the rule and the pixel widths follow
   whatever the row is given. align-items is grid's default stretch, which is what
   makes the three cards equal height and puts the dividers on one line. */
.sp-quote-testimonial-grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr;
  gap: var(--space-300);
  margin-top: var(--space-500);
}

.sp-quote-testimonial-card {
  margin: 0;
  padding: var(--space-300);
  border: var(--border-thin) solid var(--card-border);
  border-radius: var(--radius-lg);
  background: var(--paper);
  box-shadow: var(--elevation-subtle);
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
}

/* flex: 1 is what pins the attribution to the card bottom — without it a short
   quote would float its divider up and the three would no longer line up. */
.sp-quote-testimonial-quote {
  flex: 1;
  margin: 0;
  color: var(--text-body);
  font-size: var(--type-card-title-size);
  font-weight: var(--font-weight-regular);
  line-height: 26px;
  letter-spacing: var(--tracking-body);
  text-wrap: pretty;
}

/* Full card width inside the padding — unlike slide 13 there is no ordinal
   column to indent past.

   min-height is what actually puts the three dividers on one line. The divider is
   this row's border-top, so the rows have to be equal height, and they are not
   equal by content: the logo images are 28 / 15 / 11px tall (the heights the logo
   pass chose so all three WORDMARKS land on the same letterform height — Intercom
   carries an icon taller than its wordmark, which is why its image is the tall
   one).

   43 = 14 padding + 1 border + the 28px Intercom image, the tallest of the three.
   All three attributions now sit inline, so this is purely the floor that keeps
   the shorter two padded out to the same height as card 1.

   flex-wrap so an over-wide logo drops to its own line rather than forcing the
   role to break mid-phrase. */
.sp-quote-testimonial-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* 16, not 10: the dot used to sit between the role and the logo and carried the
     separation. With it gone a 10px gap read as glued together. */
  gap: var(--space-100) var(--space-200);
  min-height: 43px;
  padding-top: 14px;
  border-top: var(--border-thin) solid var(--card-border);
}

/* nowrap: the role is a job title and breaking "Engineering / Manager" across two
   lines reads as a layout accident. If it cannot fit, the logo wraps instead. */
.sp-quote-testimonial-role {
  flex: none;
  white-space: nowrap;
  color: var(--muted);
  font-size: 13px;
  font-weight: var(--font-weight-regular);
  line-height: 19px;
}

/* Height comes from the per-logo inline style the logo pass tuned so the three
   wordmarks share a letterform height; width follows the aspect ratio. */
.sp-quote-testimonial-logo {
  flex: none;
  width: auto;
  object-fit: contain;
  display: block;
}

/* Symbol-only lockup, cropped in CSS — the asset is not touched. Amplitude's PNG
   is 213x45 with the circular mark occupying an exact 45x45 square at the left
   (measured: ink runs 0-44, then a 5px gap before the wordmark), so a square box
   with object-fit: cover and a left origin lands precisely on the symbol.
   Its full lockup is 71px wide, which is what stopped card 2 fitting "role - logo"
   on one line; the symbol is 14px. */
.sp-quote-testimonial-logo[data-logo-crop="symbol"] {
  aspect-ratio: 1;
  width: auto;
  object-fit: cover;
  object-position: left center;
}

/* ---------- Numbered quote cards (slide 13) ----------

   A separate family from .sp-quote-testimonial-* on purpose. Slide 25 renders
   those classes, so restyling them to redesign slide 13 would have silently
   redesigned slide 25 too. Nothing above this comment is touched.

   The ordinals tie the cards back to the lead line ("Two jobs came up in every
   interview"), which is why the quote marks are gone: two decorative glyphs and
   two numerals in the same corner would compete. */

/* Two classes — `.slide.sp-slide` also sets `background`, so a single-class rule
   loses on specificity and the wash silently disappears. */
.slide.sp-quote-numbered {
  background: var(--grad-wash);
}

/* Columns are positioned against the stage, so the frame's own padding would
   double-offset them. */
.sp-quote-numbered .sp-frame-content {
  padding: 0;
}

.sp-quote-numbered-text {
  position: absolute;
  left: var(--slide-inset-left);
  top: var(--space-800, 64px);
  bottom: var(--space-800, 64px);
  width: var(--slide-copy-width);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 14px;
}

/* Right edge 24px, not the sample's 28: the deck runs media panels to 1016 on
   slides 9 / 14 / 15 / 16 / 17, and these cards start on the media axis, so they
   belong on the media edge rather than 4px inside it. */
.sp-quote-numbered-media {
  position: absolute;
  left: var(--slide-media-left);
  right: var(--space-300);
  top: var(--space-800, 64px);
  bottom: var(--space-800, 64px);
  margin: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-200);
}

/* Scoped past `.slide h2` (0,1,1) — a single-class title selector loses to it,
   which is exactly how three titles silently kept the wrong size until the type
   pass. This is what makes the weight-400 title actually render at 400. */
.sp-quote-numbered .sp-quote-numbered-title {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
  text-wrap: pretty;
}

.sp-quote-numbered-lead {
  margin: 0;
  color: var(--text-secondary);
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-body-line);
  text-wrap: pretty;
}

.sp-quote-numbered-card {
  margin: 0;
  padding: var(--space-300);
  border: var(--border-thin) solid var(--card-border);
  border-radius: var(--radius-lg);
  background: var(--paper);
  box-shadow: var(--elevation-subtle);
  display: flex;
  flex-direction: column;
  gap: var(--space-200);
}

/* Fixed 28px numeral column so both quotes start on one x-axis regardless of
   how wide "01" and "02" measure. Baseline-aligned so the numeral sits on the
   quote's first line, not above it. */
.sp-quote-numbered-head {
  display: grid;
  grid-template-columns: 28px 1fr;
  column-gap: var(--space-250);
  align-items: baseline;
}

.sp-quote-numbered-num {
  font-family: var(--font-label);
  font-size: var(--type-body-size);
  font-weight: var(--font-weight-regular);
  line-height: 26px;
  background: var(--grad-type);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
}

.sp-quote-numbered-quote {
  margin: 0;
  color: var(--text-body);
  font-size: var(--type-card-title-size);
  font-weight: var(--font-weight-regular);
  line-height: 26px;
  letter-spacing: var(--tracking-body);
  text-wrap: balance;
}

/* 48px = the 28px numeral column plus its 20px gap, so the rule starts under the
   quote's left edge rather than the card's padding edge. */
.sp-quote-numbered-attr {
  margin-left: 48px;
  padding-top: 14px;
  border-top: var(--border-thin) solid var(--card-border);
  display: flex;
  align-items: center;
  /* 16 to match slide 25 — the dot that used to separate these is gone. */
  gap: var(--space-200);
}

.sp-quote-numbered-role {
  color: var(--muted);
  font-size: 13px;
  font-weight: var(--font-weight-regular);
  line-height: 19px;
}

/* Height comes from the per-logo inline style set by the logo pass; width
   follows the aspect ratio. */
.sp-quote-numbered-logo {
  flex: none;
  width: auto;
  display: block;
  object-fit: contain;
}

/* ---------- Validated Problem (research spec + call recordings) ---------- */

/* Two classes: `.slide.sp-slide` also sets `background`, so a single-class
   rule here loses on specificity and the wash silently disappears. */
.sp-slide.sp-validated-problem {
  background:
    radial-gradient(70% 55% at 88% 108%, rgba(214, 217, 252, 0.85), transparent 70%),
    radial-gradient(45% 40% at 108% 85%, rgba(110, 195, 240, 0.22), transparent 65%),
    var(--paper);
}

.sp-vp-copy {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--slide-inset-left);
  width: var(--slide-copy-width);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 20px;
}

.sp-vp-head {
  display: flex;
  flex-direction: column;
  gap: var(--space-100);
}

.sp-vp-head h2 {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-medium, 500);
  letter-spacing: var(--tracking-body);
  line-height: var(--type-lead-line);
  text-wrap: pretty;
}

.sp-vp-rows {
  display: flex;
  flex-direction: column;
}

.sp-vp-row {
  display: grid;
  grid-template-columns: 110px 1fr;
  gap: var(--space-200);
  padding: 13px 0;
  border-top: var(--border-thin) solid #e6ebf1;
}

.sp-vp-row:last-child {
  border-bottom: var(--border-thin) solid #e6ebf1;
}

.sp-vp-label {
  padding-top: 1px;
  /* Matched to the steps-diagram numerals on the trust-flow slide
     (.sp-steps-copy article > b) so the two slides' sub-labels read as one
     family: gradient-clipped type rather than flat blue. */
  background: var(--grad-type);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
  font-family: var(--font-label);
  font-size: var(--type-control-size);
  font-weight: var(--font-weight-regular);
  letter-spacing: 0.08em;
  line-height: var(--type-body-line);
  text-wrap: balance;
}

.sp-vp-value {
  color: var(--text-secondary);
  font-size: 15px;
  line-height: 1.45;
  text-wrap: pretty;
}

.sp-vp-value.is-ink {
  color: var(--ink);
}

/* Values stay one colour (secondary); emphasis reads through weight only,
   so the purple labels remain the sole colour distinction. */
.sp-vp-value b {
  color: inherit;
  font-weight: var(--font-weight-medium, 500);
}

.sp-vp-media {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 556px;
}

.sp-vp-card {
  position: absolute;
  margin: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: #0d1526;
}

.sp-vp-card img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.sp-vp-card-1 {
  top: 96px;
  left: 20px;
  width: 400px;
  height: 250px;
  /* Not elevation — the back half of an intentional depth pair with
     .sp-vp-card-2. Collapsing both to one token flattens the stack. */
  box-shadow: 0 18px 44px rgba(13, 37, 61, 0.24);
  transform: rotate(-1.5deg);
}

.sp-vp-card-2 {
  top: 268px;
  left: 214px;
  width: 330px;
  height: 206px;
  /* Not elevation — the front half of the pair above. Its heavier, tighter
     shadow is what separates the two cards. */
  box-shadow: 0 20px 48px rgba(13, 37, 61, 0.28);
  transform: rotate(2deg);
}

/* One capture instead of the overlapping pair. The paired coordinates would
   strand a single card in the top-left corner, and their 1.6 aspect against the
   capture's 1.78 crops the right edge under object-fit: cover — which is exactly
   where the presenter's own video tile sits. 445x250 is 1.780 against the
   source's 1.7818, so nothing meaningful is cut. Sits square: the pair used
   rotation to read as a stack, and a lone card just looks crooked. */
.sp-vp-media-single .sp-vp-card-1 {
  top: 168px;
  left: 20px;
  width: 445px;
  height: 250px;
  transform: none;
}

/* ---------- Why auto-tagging (tag-settings product screen) ---------- */

/* Two classes — see the note on `.sp-slide.sp-validated-problem`. */
.sp-slide.sp-why-tagging {
  background:
    radial-gradient(70% 55% at 90% 108%, rgba(214, 217, 252, 0.85), transparent 70%),
    radial-gradient(45% 40% at 110% 85%, rgba(110, 195, 240, 0.22), transparent 65%),
    var(--paper);
}

/* PRODUCT-MOCK PALETTE — .sp-wt-* imitates the slide-36 Tag Settings screen.
   The 15 raw hex text colours in this family (#101828 #344054 #475467 #667085
   #98a2b3 #6e56f0 #4530b8) are that product's palette, not deck tokens. Do not
   convert them: a mock painted in deck colours reads as fake. Small sizes here
   are correct too — this is application UI, not deck copy. */
.sp-wt-copy {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--slide-inset-left);
  width: var(--slide-copy-width);
  z-index: 3;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 14px;
}

.sp-wt-copy h2 {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-medium, 500);
  letter-spacing: var(--tracking-body);
  line-height: var(--type-lead-line);
  text-wrap: pretty;
}

.sp-wt-lead {
  margin: 0;
  color: var(--text-secondary);
  font-size: 16px;
  line-height: 1.5;
  text-wrap: pretty;
}

.sp-wt-lead b {
  color: var(--ink);
  font-weight: 600;
}

.sp-wt-screen {
  position: absolute;
  left: var(--slide-media-left);
  top: 40px;
  width: 720px;
  height: 600px;
  box-sizing: border-box;
  padding: 26px 32px 26px 28px;
  background: #fff;
  border: 1px solid #eaecf0;
  border-radius: 16px 16px 0 0;
  box-shadow: var(--elevation-2);
  overflow: hidden;
  font-family: "Inter", var(--font-sans);
}

.sp-wt-screen-title {
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: #101828;
}

.sp-wt-screen-desc {
  margin: 6px 0 0;
  max-width: 560px;
  font-size: 12.5px;
  line-height: 1.5;
  color: #667085;
}

.sp-wt-section-label {
  margin-top: 18px;
  font-size: 13px;
  font-weight: 600;
  color: #344054;
}

.sp-wt-divider {
  height: 1px;
  margin: 8px 0 12px;
  background: #eaecf0;
}

.sp-wt-controls {
  display: flex;
  gap: 28px;
}

.sp-wt-control {
  display: flex;
  align-items: center;
  gap: 12px;
}

.sp-wt-control-label {
  font-size: 12.5px;
  color: #475467;
  white-space: nowrap;
}

.sp-wt-select {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  box-sizing: border-box;
  height: 32px;
  padding: 0 11px;
  border: 1px solid #d0d5dd;
  border-radius: 8px;
  background: #fff;
  font-size: 12.5px;
  color: #344054;
  white-space: nowrap;
}

.sp-wt-select-lg { width: 206px; }
.sp-wt-select-sm { width: 118px; }

.sp-wt-select-prop,
.sp-wt-select-field {
  height: 30px;
  padding: 0 10px;
  font-size: 12px;
}

.sp-wt-select-prop { width: 132px; gap: 8px; }

.sp-wt-select-field {
  width: 96px;
  gap: 6px;
  overflow: hidden;
}

.sp-wt-select-field > span {
  overflow: hidden;
  text-overflow: ellipsis;
}

.sp-wt-caret {
  flex: none;
  width: 12px;
  height: 12px;
}

.sp-wt-tabs {
  display: flex;
  align-items: center;
  margin-top: 20px;
  border-bottom: 1px solid #eaecf0;
}

.sp-wt-tablist {
  display: flex;
  flex: 1;
  gap: 22px;
}

.sp-wt-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding-bottom: 9px;
  font-size: 13px;
  font-weight: 500;
  color: #667085;
  white-space: nowrap;
}

.sp-wt-tab.is-active {
  font-weight: 600;
  color: #6e56f0;
  border-bottom: 2px solid #6e56f0;
}

.sp-wt-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 17px;
  height: 17px;
  padding: 0 5px;
  border-radius: 999px;
  background: #f2f4f7;
  color: #667085;
  font-size: 10.5px;
  font-weight: 650;
}

.sp-wt-badge.is-active {
  background: #ece9fe;
  color: #4530b8;
}

.sp-wt-sync {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-bottom: 8px;
  white-space: nowrap;
}

.sp-wt-sync-time {
  font-size: 11.5px;
  color: #98a2b3;
}

.sp-wt-sync-time span {
  color: #667085;
}

.sp-wt-sync-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  font-weight: 500;
  color: #6e56f0;
}

.sp-wt-sync-btn svg {
  width: 13px;
  height: 13px;
}

.sp-wt-search {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  box-sizing: border-box;
  width: 260px;
  height: 34px;
  margin-top: 14px;
  padding: 0 12px;
  border: 1px solid #d0d5dd;
  border-radius: 8px;
  color: #98a2b3;
  font-size: 12.5px;
}

.sp-wt-search svg {
  width: 15px;
  height: 15px;
}

.sp-wt-table {
  width: 100%;
  margin-top: 14px;
  border-collapse: collapse;
  table-layout: fixed;
}

.sp-wt-table th {
  padding: 8px 12px;
  border-bottom: 1px solid #eaecf0;
  color: #667085;
  font-size: 10.5px;
  font-weight: 650;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-align: left;
  white-space: nowrap;
}

.sp-wt-col-tag { width: 25%; }
.sp-wt-col-assets { width: 13%; text-align: right; }
.sp-wt-col-prop { width: 23%; }
.sp-wt-col-field { width: 15%; }
.sp-wt-col-mask { width: 11%; text-align: center; padding: 8px 6px; }
.sp-wt-col-auto { width: 13%; text-align: center; padding: 8px 6px; }

.sp-wt-table td {
  padding: 7px 12px;
  border-bottom: 1px solid #f2f4f7;
  background: #fff;
}

.sp-wt-table tr.is-highlight td {
  background: #f6f4ff;
}

.sp-wt-cell-tag {
  border-left: 3px solid transparent;
}

.sp-wt-table tr.is-highlight .sp-wt-cell-tag {
  border-left-color: #6e56f0;
}

.sp-wt-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 24px;
  padding: 0 9px 0 6px;
  border: 1px solid;
  border-radius: 7px;
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
}

.sp-wt-tag-icon {
  display: block;
  flex: none;
  width: 13px;
  height: 13px;
}

.sp-wt-cell-count {
  text-align: right;
  font-size: 13px;
  color: #344054;
  font-variant-numeric: tabular-nums;
}

.sp-wt-cell-center {
  padding: 7px 6px;
  text-align: center;
}

.sp-wt-toggle {
  position: relative;
  display: inline-flex;
  width: 34px;
  height: 20px;
  border-radius: 999px;
  background: #e4e7ec;
  vertical-align: middle;
}

.sp-wt-toggle::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  box-shadow: var(--elevation-hairline);
}

.sp-wt-toggle.is-on {
  background: #6e56f0;
}

.sp-wt-toggle.is-on::after {
  left: 16px;
  box-shadow: var(--elevation-hairline);
}

.sp-wt-check {
  width: 15px;
  height: 15px;
  vertical-align: middle;
}

/* ---------- Redesign impact (stat trio) ---------- */

/* Specificity note: `.slide.sp-slide` sets `padding: 0`, so this rule must
   match with two classes or the frame padding is dropped. */
.sp-slide.sp-redesign-impact {
  box-sizing: border-box;
  /* Left edge on the deck axis; the other three stay as laid out. */
  padding: 64px 64px 64px var(--slide-inset-left);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 56px;
  background:
    radial-gradient(70% 55% at 88% 108%, rgba(214, 217, 252, 0.85), transparent 70%),
    radial-gradient(45% 40% at 108% 85%, rgba(110, 195, 240, 0.22), transparent 65%),
    var(--paper);
}

.sp-ri-head {
  display: flex;
  flex-direction: column;
  gap: var(--space-150);
  max-width: 640px;
}

.sp-ri-head h2 {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-medium, 500);
  letter-spacing: var(--tracking-body);
  line-height: var(--type-lead-line);
  text-wrap: balance;
}

.sp-ri-grid {
  display: grid;
  /* Column count comes from the data, so the row stays balanced whether the
     slide carries two stats or three. */
  grid-template-columns: repeat(var(--sp-ri-count, 3), minmax(0, 1fr));
}

.sp-ri-stat {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 0 44px;
  border-left: var(--border-thin) solid #e6ebf1;
}

.sp-ri-stat:first-child {
  padding: 0 44px 0 0;
  border-left: 0;
}

.sp-ri-stat:last-child {
  padding-right: 0;
}

.sp-ri-value {
  color: var(--blue);
  font-size: 84px;
  font-weight: var(--font-weight-medium, 500);
  line-height: 0.9;
  letter-spacing: -0.035em;
  font-variant-numeric: tabular-nums;
}

.sp-ri-caption {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.sp-ri-label {
  color: var(--ink);
  font-size: 16px;
  font-weight: 600;
  line-height: 23px;
}

.sp-ri-note {
  color: var(--muted);
  font-size: 14px;
  line-height: 20px;
}

/* ---------- Beyond Acquisition (external validation / LinkedIn post) ---------- */

/* Two classes — `.slide.sp-slide` also sets `background`. */
.sp-slide.sp-beyond-acquisition {
  background:
    radial-gradient(70% 55% at 85% 108%, rgba(214, 217, 252, 0.85), transparent 70%),
    radial-gradient(45% 40% at 108% 85%, rgba(110, 195, 240, 0.22), transparent 65%),
    var(--paper);
}

/* PRODUCT-MOCK PALETTE — .sp-ba-* imitates the slide-27 LinkedIn post.
   The 8 raw hex text colours in this family (#0a66c2 LinkedIn blue, #8894a6
   #35404f #4a5666 #3f2bd6) are LinkedIn's palette, not deck tokens. Do not
   convert them: a mock painted in deck colours reads as fake. */
.sp-ba-copy {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--slide-inset-left);
  width: var(--slide-copy-width);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 16px;
}

.sp-ba-copy h2 {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-medium, 500);
  letter-spacing: var(--tracking-body);
  line-height: var(--type-lead-line);
}

.sp-ba-lead {
  margin: 0;
  max-width: 320px;
  color: var(--text-secondary);
  /* Down from 20px: it sits beside the LinkedIn card, and at lead size it
     competed with the post rather than introducing it. */
  font-size: 16px;
  line-height: 1.5;
  text-wrap: pretty;
}

.sp-ba-card {
  position: absolute;
  top: 40px;
  bottom: 40px;
  right: 44px;
  left: var(--slide-media-left);
  box-sizing: border-box;
  padding: 24px 26px;
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1px solid var(--hairline);
  border-radius: 14px;
  box-shadow: var(--elevation-card);
}

.sp-ba-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.sp-ba-avatar {
  flex: none;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  object-fit: cover;
}

.sp-ba-identity {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.sp-ba-name-row {
  display: flex;
  align-items: center;
  gap: 7px;
}

.sp-ba-name {
  color: var(--ink);
  font-size: 15px;
  font-weight: 700;
}

.sp-ba-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  border-radius: 3px;
  background: #0a66c2;
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.sp-ba-follow {
  font-size: 13px;
  color: #8894a6;
}

.sp-ba-headline {
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--muted);
}

.sp-ba-time {
  font-size: 12px;
  color: #8894a6;
}

.sp-ba-menu {
  display: flex;
  gap: 3px;
  align-self: flex-start;
  padding-top: 4px;
}

.sp-ba-menu span {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: #b4bdca;
}

.sp-ba-body {
  margin-top: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  font-size: 14px;
  line-height: 1.5;
  color: #35404f;
}

.sp-ba-body p {
  margin: 0;
}

.sp-ba-brand {
  color: #0a66c2;
  font-weight: 500;
}

.sp-ba-mark {
  background: rgba(83, 58, 253, 0.12);
  color: #3f2bd6;
  font-weight: 600;
  padding: 1px 5px;
  border-radius: 4px;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

.sp-ba-media {
  margin-top: 14px;
  border: 1px solid #e6ebf1;
  border-radius: 8px;
  overflow: hidden;
  background: #fbfcfe;
}

.sp-ba-media img {
  display: block;
  width: 100%;
  height: 188px;
  object-fit: cover;
  object-position: top center;
}

.sp-ba-footer {
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid #eceff3;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.sp-ba-reactions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.sp-ba-dots {
  display: flex;
}

.sp-ba-dots i {
  width: 19px;
  height: 19px;
  border-radius: 50%;
  border: 1.5px solid #fff;
}

.sp-ba-dots i:nth-child(1) { background: #378fe9; }
.sp-ba-dots i:nth-child(2) { background: #e0b34e; margin-left: -6px; }
.sp-ba-dots i:nth-child(3) { background: #df704d; margin-left: -6px; }

.sp-ba-reaction-text {
  font-size: 12.5px;
  color: var(--muted);
}

.sp-ba-reaction-text strong {
  font-weight: 600;
  color: #4a5666;
}

.sp-ba-stats {
  font-size: 12.5px;
  color: #8894a6;
}

/* ---------- Lineage Demo (live product iframe in a browser frame) ---------- */

/* Two classes — `.slide.sp-slide` also sets `background`.
   Headerless: no title row, so the slide's only job is to hold the browser
   window off the top edge by 24. Left, right and bottom stay full-bleed. That
   24 is not slack to reclaim — flush to t0 would sit the window's 12px top
   corners on the stage edge, where they read as a clipping bug, and would put
   the upward shadow nowhere. */
.sp-slide.sp-lineage-demo {
  display: flex;
  flex-direction: column;
  padding-top: var(--space-300);
  background:
    radial-gradient(70% 55% at 88% 108%, rgba(214, 217, 252, 0.85), transparent 70%),
    radial-gradient(45% 40% at 108% 85%, rgba(110, 195, 240, 0.22), transparent 65%),
    var(--paper);
}

.sp-ld-window {
  flex: 1 1 auto;
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid #e6ebf1;
  border-bottom: none;
  border-radius: 12px 12px 0 0;
  overflow: hidden;
  background: #fff;
  /* Not elevation — an upward shadow on a bottom-attached panel, so the
     offset is negative. */
  box-shadow: 0 -1px 24px rgba(13, 37, 61, 0.1);
}

.sp-ld-chrome {
  flex: none;
  height: 38px;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 16px;
  background: #f4f6fa;
  border-bottom: 1px solid #e6ebf1;
}

.sp-ld-dots {
  display: flex;
  gap: 7px;
}

.sp-ld-dots i {
  width: 11px;
  height: 11px;
  border-radius: 50%;
}

.sp-ld-dots i:nth-child(1) { background: #ff5f57; }
.sp-ld-dots i:nth-child(2) { background: #febc2e; }
.sp-ld-dots i:nth-child(3) { background: #28c840; }

.sp-ld-url {
  flex: 1;
  max-width: 340px;
  height: 22px;
  display: flex;
  align-items: center;
  padding: 0 12px;
  border-radius: 6px;
  background: #fff;
  border: 1px solid #e6ebf1;
  font-size: 12px;
  color: var(--muted);
}

.sp-ld-viewport {
  flex: 1 1 auto;
  position: relative;
  overflow: hidden;
}

.sp-ld-poster,
.sp-ld-frame {
  position: absolute;
  top: 0;
  left: 0;
  border: 0;
}

.sp-ld-poster {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top left;
  z-index: 1;
}

.sp-ld-frame {
  width: 125%;
  height: 125%;
  transform: scale(0.8);
  transform-origin: top left;
  z-index: 2;
  background: #faf9f5;
}

/* ---------- Strength statement ---------- */
/* Left copy column against a full-height image panel. Positioned absolutely to
   match the handoff's own geometry rather than the standard frame padding —
   the panel deliberately bleeds closer to the edges than a normal slide. */
.sp-strength-copy {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--slide-inset-left);
  width: var(--slide-copy-width);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-150);
}

/* Scoped down to the deck's 20px step, NOT via --type-statement-*. That token
   pair is shared by every statement and principle slide (styles.css 3701/3713/
   3719, this file 2942/2952/2958) — retuning it would shrink all of them. The
   line-height and tracking have to travel with the size: 42px leading under
   20px type reads as a list, and --tracking-case (-0.025em) is a display value
   for 40px and up, where the deck's rule below 20px is 0. */
.sp-strength-copy h2 {
  margin: 0;
  color: var(--ink);
  font-size: var(--type-lead-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--type-lead-line);
  letter-spacing: var(--tracking-body);
  text-wrap: balance;
}

.sp-strength-media {
  position: absolute;
  top: var(--space-300);
  right: var(--space-300);
  bottom: var(--space-300);
  left: var(--slide-media-left);
  border-radius: var(--radius-xl);
  overflow: hidden;
  /* Sits behind the photo, so it only shows if the image fails — degrading to
     the intended wash rather than a white hole. */
  background:
    radial-gradient(60% 50% at 18% 8%, rgba(102, 94, 253, 0.34), transparent 60%),
    radial-gradient(50% 40% at 88% 28%, rgba(242, 169, 196, 0.38), transparent 65%),
    radial-gradient(55% 45% at 55% 95%, rgba(110, 195, 240, 0.38), transparent 60%),
    linear-gradient(160deg, #edeffb, #f6f1fa);
}

.sp-strength-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* The panel is near-square (524x537) and the art is 1.9:1, so cover crops
     ~24% off each side. At 72% the hand pulling the thread sat right on the
     cut and read as an accident; 85% brings the whole hand in while the
     tangle still fills the frame. */
  object-position: 85% center;
}

/* ---- Numbered lists match the showcase-decision treatment on slide 9 ----
   The numerals are proportional in DM Sans ("01" is 18.3px, "03" is 23.1px),
   which staggers the titles by ~5px unless the column is fixed and the digits
   are tabular. Same 24px column, same gradient-clipped numeral. */
.sp-steps-copy article > b,
.sp-step-spotlight-num {
  flex: none;
  width: 24px;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono, var(--font-label));
  font-size: 18px;
  font-weight: var(--font-weight-medium, 500);
  line-height: 26px;
  letter-spacing: normal;
  background: var(--grad-type);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
}

/* Grid column has to follow the numeral, or the title indents off a stale width. */
.sp-steps-copy article {
  grid-template-columns: 24px minmax(0, 1fr);
  align-items: start;
}
.sp-steps-copy article > div { padding-top: 2px; }

.sp-step-spotlight-step {
  display: flex;
  gap: var(--space-150);
  align-items: flex-start;
}
.sp-step-spotlight-step-title { padding-top: 2px; }

/* Match slide 9's decision list exactly: body size, not card-title size —
   18px against its 16px was the visible mismatch. Active picks up --accent,
   the same colour the "40%" in the subtitle uses. */
.sp-step-spotlight-step-title {
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
}
.sp-step-spotlight-step.active .sp-step-spotlight-step-title {
  color: var(--accent);
  font-weight: var(--font-weight-medium, 600);
}

/* Same alignment to slide 9's decision list as the spotlight steps above:
   16px title, not the 18px card-title step, and the body line-height back on
   the 24px token instead of a one-off 23px. */
.sp-steps-copy article h3 {
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
}
.sp-steps-copy article p {
  line-height: var(--type-body-line);
}

/* ---- Slide 33 (ai-quality-research) column balance ----
   validatedProblemSlide is this slide only, so these override the shared
   --slide-copy-width without reaching the seven other copy columns that use it.
   The spec table was living in 332px and wrapping every value; 440 gives the
   Goal/Target/Format rows room, and the media and its card move right to match. */
.sp-validated-problem .sp-vp-copy { width: 440px; }
.sp-validated-problem .sp-vp-media { left: 600px; }
.sp-validated-problem .sp-vp-media-single .sp-vp-card-1 {
  width: 400px;
  height: 225px;
}

/* ---- p44 glass moves follow p11's hypothesis cards ----
   The panel already says "Same anatomy as .sp-hypothesis-card", but three
   values had drifted: panel radius 16 vs 20, card border alpha .78 vs .85 and
   blur 20 vs 18. p11 is the reference the comment points at, so p44 matches it. */
.sp-glass-moves-panel { border-radius: var(--radius-xl); }
.sp-glass-moves-panel article {
  border-color: rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
}

/* ---- Numbered lists: one baseline, one colour ----
   The numeral runs 18px/26px against 16px/24px text, so aligning the boxes
   (flex-start plus a 2px nudge) left the figures sitting ~2px high on slide 9
   and 34. Baseline alignment makes the two share a line regardless of size,
   and the nudges come out. p34's titles also drop to the same secondary
   colour and regular weight slide 9 uses — they were ink at 500. */
.sp-showcase-decision,
.sp-step-spotlight-step,
.sp-steps-copy article {
  align-items: baseline;
}
.sp-showcase-decision-copy,
.sp-step-spotlight-step-title,
.sp-steps-copy article > div {
  padding-top: 0;
}
.sp-steps-copy article h3 {
  color: var(--text-secondary);
  font-weight: var(--font-weight-regular);
}

/* Numerals sit at the text size, not a step above it — 18px against 16px copy
   was reading as two different type sizes in the same row. */
.sp-showcase-decision-num,
.sp-step-spotlight-num,
.sp-steps-copy article > b {
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
}

/* ── Slide 30 · observed problem, the evidence ──────────────────────────────
   The deck's coordinate contract: text starts at 128, the copy column caps at
   332 and ends at 460, the media panel runs 492 → right 24 inside the 24px
   page gutter. Text never leaves the axis. */
.sp-evidence .sp-frame-content {
  position: relative;
  padding: 0;
}

.sp-evidence-copy {
  position: absolute;
  left: 128px;
  top: 56px;
  bottom: 56px;
  width: 332px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 26px;
}

.sp-evidence-copy > i {
  width: 48px;
  height: 2px;
  background: var(--grad-hairline);
}

/* The handoff specifies 40/48. The deck loads DM Sans as static instances
   rather than with the opsz axis its design file uses, so display type renders
   ~11% wider here: "Adoption was loud." measures 344px against the 332px
   column cap and drops "loud." onto its own line. 38px brings it back to one
   line per span. Loading the variable axis would let this return to 40px — it
   would also reflow every headline in the deck. */
.sp-evidence .sp-evidence-statement {
  margin: 0;
  font-size: 38px;
  font-weight: var(--font-weight-regular);
  line-height: 46px;
  letter-spacing: -0.015em;
  color: var(--ink);
}

.sp-evidence .sp-evidence-statement span { display: block; }

/* On top of the 26px column gap — the card is deliberately dropped away
   from the headline. */
.sp-evidence-quote {
  margin: 30px 0 0;
  box-sizing: border-box;
  padding: 20px 24px;
  border: var(--border-thin) solid var(--card-border);
  border-radius: var(--radius-lg);
  background: var(--paper);
  box-shadow: 0 2px 10px rgba(13, 37, 61, 0.05);
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.sp-evidence-quote blockquote {
  margin: 0;
  font-size: 17px;
  font-weight: var(--font-weight-regular);
  line-height: 25px;
  color: var(--ink);
  text-wrap: pretty;
}

.sp-evidence-quote figcaption {
  display: flex;
  align-items: baseline;
  gap: var(--space-125, 10px);
  font-size: 13px;
  line-height: 19px;
  color: var(--muted);
}

.sp-evidence-quote-logo {
  flex: none;
  width: auto;
  max-width: 110px;
  object-fit: contain;
  display: block;
  align-self: center;
  filter: grayscale(1) brightness(0.55);
}

.sp-evidence-panel {
  position: absolute;
  left: 492px;
  right: 24px;
  top: 24px;
  bottom: 24px;
  border-radius: var(--radius-xl);
  overflow: hidden;
  background: var(--grad-aurora-panel);
}

.sp-evidence-panel-inner {
  position: absolute;
  inset: 32px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 30px;
}

.sp-evidence-stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-100);
}

.sp-evidence-stat-row {
  display: flex;
  align-items: center;
  gap: var(--space-150);
}

/* The largest element on the slide, and that is the point — it used to be the
   smallest, greyest text here. */
.sp-evidence-stat-value {
  font-size: 64px;
  font-weight: var(--font-weight-medium, 500);
  line-height: 64px;
  letter-spacing: -0.03em;
  background: var(--grad-type);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
}

.sp-evidence-stat-arrow {
  flex: none;
  margin-bottom: 4px;
  stroke: var(--emph-text);
}

.sp-evidence-stat-caption {
  font-size: 16px;
  font-weight: var(--font-weight-regular);
  line-height: 24px;
  color: var(--text-secondary);
  text-wrap: pretty;
}

.sp-evidence-chart {
  display: flex;
  flex-direction: column;
  gap: var(--space-150);
}

.sp-evidence-chart-svg {
  display: block;
  width: 100%;
  height: auto;
}

.sp-evidence-chart-label {
  align-self: center;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.sp-ev-axis,
.sp-ev-guide { stroke: var(--hairline); stroke-width: 1; }
.sp-ev-guide { stroke-dasharray: 3 4; }

.sp-ev-line {
  stroke-width: 2.5;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.sp-ev-peak { fill: var(--grad-blue); }
.sp-ev-trough { fill: var(--emph-text); }

.sp-ev-peak-label {
  font-size: 13px;
  font-weight: var(--font-weight-medium, 500);
  fill: var(--ink);
}

.sp-ev-date { font-size: 12px; fill: var(--muted); }
.sp-ev-date-end { fill: var(--emph-text); }

/* The trace and its markers stage in; the 67%, the caption, the headline, the
   quote, the axis and the guide never move. The slide reads in frame 1. */
@keyframes opDraw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes opFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes opRise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.sp-ev-line { stroke-dasharray: 1; animation: opDraw 2900ms cubic-bezier(.32, .02, .4, 1) 300ms both; }
.sp-ev-area { animation: opFade 1300ms ease-out 1100ms both; }
.sp-ev-peak { animation: opFade 450ms ease-out 1300ms both; }
.sp-ev-peak-label,
.sp-evidence-chart .sp-ev-date:not(.sp-ev-date-end) { animation: opFade 550ms ease-out 1420ms both; }
.sp-ev-trough { animation: opFade 450ms ease-out 3200ms both; }
.sp-ev-date-end { animation: opFade 550ms ease-out 3200ms both; }
.sp-evidence-stat-arrow { animation: opRise 700ms cubic-bezier(.22, .61, .36, 1) 3200ms both; }

@media (prefers-reduced-motion: reduce) {
  .sp-evidence [data-anim] {
    animation: none !important;
    stroke-dashoffset: 0 !important;
    opacity: 1 !important;
    transform: none !important;
  }
}
