/* ==========================================================================
   PPSC DESIGN SYSTEM — components + layout
   Organized by atomic design layer. Every value references a token from
   ppsc-tokens.css — never a raw hex/px value.

   LOADING — this file is NOT standalone
     ppsc-tokens.css -> ppsc-chrome.css -> ppsc-ds.css, in that order.
   ppsc-chrome.css declares the primitives this file uses:
   .ppsc-ds-section, .ppsc-ds-container, the .ppsc-ds-btn family,
   --ppsc-ds-focus-ring, body { margin: 0 }, and the shared tagline/caps
   local values. The site header needs them too, on pages that never
   load this file.

   Only the design system pages load this file: the global reset below
   is safe on a page built entirely from this design system, not on a
   legacy page.

   Layers in this file (in order):
     LAYOUT     — page-level structural pieces (surfaces, stack, page)
     ATOMS      — links, headings, labels, icons, tags
     MOLECULES  — small assemblies (stat cell, card, form field)
     ORGANISMS  — full page sections (hero, accordion group, …)
     RESPONSIVE — every @media override, grouped by breakpoint (see note
                  at that section — do not add @media blocks inside a
                  component's own section)

   NAMING / SCOPING
   - Prefix everything ppsc-ds-
   - A component is styled by its own class alone — never depends on a
     wrapper as an ancestor selector.

   SECTIONS — naked vs. self-contained organisms
   Naked organisms have no surface or vertical space of their own: the
   wrapping .ppsc-ds-section owns them. The self-contained ones keep
   theirs because their background is identity, not placement:

     Naked (no background, no padding of their own):
       - .ppsc-ds-intro-section
       - .ppsc-ds-additional-links
       - .ppsc-ds-cards-cluster
       - .ppsc-ds-highlight-card
       - .ppsc-ds-icon-grid
       - .ppsc-ds-media-embed
       - .ppsc-ds-accordion
       - .ppsc-ds-two-column-content
       - .ppsc-ds-fast-facts (except its Photograph theme, which owns
         the photo band the same way the CTA banner's does)
       - .ppsc-ds-content
       - .ppsc-ds-message-section (and the nested .ppsc-ds-message box,
         whose theme follows the section)
       - .ppsc-ds-gallery-slider
       - .ppsc-ds-testimonial-block (also the positioning box for its
         decorative blurs)
       - .ppsc-ds-tabs-selector
       - .ppsc-ds-cta-banner — the band behind it is a section surface
         (Teal = --surface-accent-strong); only the CARD carries a
         theme (white / white + stroke / gradient), because the card's
         look is the component's identity.

     Fully self-contained (background AND padding stay):
       - .ppsc-ds-hero — the dark blue is the component's identity, and
         it also owns min-height / overflow / the positioning context
         its absolutely-placed blur decorations depend on. The height
         is --ppsc-ds-hero-height in LOCAL VALUES.
       - .ppsc-ds-page-header — same reason as the Hero: its band colour
         and blurs are identity, and the doc locks its spacing.
       - .ppsc-ds-header and .ppsc-ds-alert-bar, in ppsc-chrome.css.

   NOTE on gaps between stacked peers: .ppsc-ds-section__stack has NO
   gap. Spacing between blocks comes from each block's own
   .ppsc-ds-pad-* utilities, and one side owns each gap (block above
   sets pad-bottom, block below sets pad-top-none) so paddings never
   add up.

   NOTE on mobile: the xl / 2xl / 3xl .ppsc-ds-pad-* utilities use the
   fluid space pairs, so they scale with the viewport on their own
   (3xl: 72px on phones → 108px at the 1332px container). Do NOT add
   per-component mobile padding overrides — the utilities are last in
   the file and would beat them.
   ========================================================================== */

/* ============================================================
   LOCAL VALUES
   Figma values with no matching token in ppsc-tokens.css. Every rule
   refers to these names rather than the literal, so replacing one
   with a token is a single edit here.
   ============================================================ */
:root {
  /* Hero */
  --ppsc-ds-hero-height: 370px; /* Figma frame */
  --ppsc-ds-hero-eyebrow-gap: 10px; /* Figma "Eyebrow" row */

  /* CTA banner */
  --ppsc-ds-cta-photo-overlay: var(--opacity-70); /* Photograph theme, doc: 70% */

  /* Cards cluster, Horizontal card */
  --ppsc-ds-card-media-width: 240px; /* Figma media column */
  --ppsc-ds-card-media-min-height: 200px; /* Figma media frame */

  /* Fast facts */
  --ppsc-ds-fast-facts-number-size: 86px; /* Figma stat number, no step token */
  --ppsc-ds-fast-facts-number-size-mobile: 64px; /* Figma mobile stat number */
  --ppsc-ds-fast-facts-photo-overlay: var(--opacity-70); /* Photograph theme, Figma 70% */

  /* Content */
  --ppsc-ds-content-sup-size: 0.645em; /* Figma 11.61px on 18px text */
  --ppsc-ds-content-marker-1: 16.44px; /* Figma bullet box, level 1 */
  --ppsc-ds-content-marker-2: 14px; /* level 2 */
  --ppsc-ds-content-marker-3: 12px; /* level 3 */
  --ppsc-ds-content-bullet-1: 8.44px; /* Figma bullet square, level 1 */
  --ppsc-ds-content-bullet-2: 6px; /* level 2 */
  --ppsc-ds-content-bullet-3: 4px; /* level 3 */
  --ppsc-ds-content-ol-marker: 20px; /* Figma number box */
  --ppsc-ds-content-media-ratio: 1344 / 756; /* Figma Media, 16:9 */
  --ppsc-ds-content-quote-mark-mobile: 80px; /* Figma mobile quote mark height */

  /* Page header — blur centres, from the band's horizontal centre and
     bottom edge (Figma frames) */
  --ppsc-ds-page-header-blur-1-x: 432.22px;
  --ppsc-ds-page-header-blur-1-y: 155.11px;
  --ppsc-ds-page-header-blur-2-x: 569.24px;
  --ppsc-ds-page-header-blur-2-y: 177.63px;

  /* Hanging opening quote mark (Content pull quote, Testimonial block):
     Figma pulls the first line back by 0.45em */
  --ppsc-ds-quote-hang: 0.45em;
  --ppsc-ds-quote-hang-ratio: 0.45; /* same, as a number for calc() */

  /* Testimonial block — blur centres from the band's horizontal centre
     and bottom edge (Figma frames), slide width, slider dots */
  --ppsc-ds-testimonial-block-b1-x: 636.32px;
  --ppsc-ds-testimonial-block-b1-y: 206.9px;
  --ppsc-ds-testimonial-block-b2-x: 957.62px;
  --ppsc-ds-testimonial-block-b2-y: 18.2px;
  --ppsc-ds-testimonial-block-carousel-b1-x: 632.32px;
  --ppsc-ds-testimonial-block-carousel-b1-y: 190.9px;
  --ppsc-ds-testimonial-block-carousel-b2-x: 953.62px;
  --ppsc-ds-testimonial-block-carousel-b2-y: 2.2px;
  --ppsc-ds-testimonial-block-slide-width: 620px;
  --ppsc-ds-testimonial-block-mark-mobile: 80px;
  --ppsc-ds-testimonial-block-media-ratio: 1344 / 756; /* Figma mobile photo */

  /* Pagination (slider dots + arrows, Figma "Pagination") */
  --ppsc-ds-pagination-dot: 8px;
  --ppsc-ds-pagination-dot-gap: 8px;
  --ppsc-ds-pagination-arrow-pad: 12px; /* 24px icon in a 48px circle */

  /* Gallery slider */
  --ppsc-ds-gallery-slider-height: 306px; /* Figma photo height, desktop */
  --ppsc-ds-gallery-slider-mobile-size: 260px; /* Figma photo, mobile (square) */

  /* Media embed */
  --ppsc-ds-media-info-gap: 10px; /* Figma caption → metadata */

  /* Tabs selector */
  --ppsc-ds-tabs-media-height: 378px; /* Figma panel image, desktop */
  --ppsc-ds-z-bottom-bar: 9; /* under the header (10), so the mobile
                               drawer still opens over it */
}

/* ============================================================
   RESET — the reason this file is not loaded sitewide
   A universal reset is safe on a page built entirely from this design
   system and unsafe on a legacy page. body { margin: 0 } and
   --ppsc-ds-focus-ring are in ppsc-chrome.css, which loads everywhere.
   ============================================================ */
* {
  margin: 0;
  padding: 0;
}

/* The legacy styles.css sets text-transform: uppercase and
   letter-spacing on bare button. This file loads after it, so the same
   bare selector wins here and covers every design system button (tabs,
   selector cards, accordion questions…). Things that are caps on
   purpose (tags, small labels) set it with their own class, which
   still wins. Same fix as the header buttons in ppsc-chrome.css. */
button {
  text-transform: none;
  letter-spacing: normal;
}

/* ============================================================
   LAYOUT
   Three shared primitives:
   - .ppsc-ds-section — the band. Goes on the outer element. Owns the
     horizontal gutter, plus the surface via --surface-default / --surface-neutral /
     --surface-subtle and the outer vertical space via the .ppsc-ds-pad-*
     utilities. A component never sets its own section background.
   - .ppsc-ds-container — goes on a child div directly inside the
     section. Caps content at the max content width and centers
     it. Never carries background or gutter itself.
   - .ppsc-ds-section__stack — use when several components share one
     band; they sit inside as independent peers, each keeping its own
     class and setting its own space with .ppsc-ds-pad-*.

   Pattern (single component in a band):
     <section class="ppsc-ds-hero ppsc-ds-section">
       <div class="ppsc-ds-container"> ...content... </div>
     </section>

   Pattern (several components sharing one band):
     <section class="ppsc-ds-section ppsc-ds-section--surface-neutral
                     ppsc-ds-pad-top-xl ppsc-ds-pad-bottom-xl">
       <div class="ppsc-ds-container ppsc-ds-section__stack">
         <div class="ppsc-ds-intro-section ppsc-ds-pad-bottom-none">…</div>
         <div class="ppsc-ds-cards-cluster ppsc-ds-pad-top-xl">…</div>
       </div>
     </section>

   .ppsc-ds-section and .ppsc-ds-container themselves are DECLARED in
   ppsc-chrome.css, because the header markup uses them too and the
   chrome has to stand alone. They are documented here because this is
   where the model they belong to is explained. Page-level pieces —
   the surface modifiers, .ppsc-ds-section__stack and .ppsc-ds-page —
   stay in this file.
   ============================================================ */

/* Section surface (background) — owned by the section layer, same model
   as the vertical-padding modifiers at the end of this file. A component
   never sets its own section background; the wrapping .ppsc-ds-section does. */
.ppsc-ds-section--surface-default {
  background: var(--surface-default);
} /* #FFFFFF */
.ppsc-ds-section--surface-neutral {
  background: var(--surface-neutral);
} /* #F8F7F7 */
.ppsc-ds-section--surface-subtle {
  background: var(--surface-subtle);
} /* #F0FCFF */
.ppsc-ds-section--surface-accent-strong {
  background: var(--surface-accent-strong);
} /* #04A4C8 — teal band, e.g. behind a CTA Banner */
.ppsc-ds-section--surface-inverse {
  background: var(--surface-inverse);
} /* #0B3B60 — dark blue band, e.g. a Dark Highlight Card */

/* Stacks multiple components in one section band. Spacing BETWEEN the
   blocks is NOT set here — each component declares its own top/bottom
   space via the .ppsc-ds-pad-top-* / .ppsc-ds-pad-bottom-* utilities,
   since grouped blocks use different spacing. This is purely the column
   stacking context. */
.ppsc-ds-section__stack {
  display: flex;
  flex-direction: column;
}

/* Page-level wrapper, on <main>. Its only job is to clip the horizontal
   overflow of full-bleed bands: those are 100vw wide, and 100vw counts
   the scrollbar, so on a platform with a classic (space-taking)
   scrollbar the band is a scrollbar-width wider than the viewport and
   the whole page scrolls sideways. macOS and Ubuntu overlay scrollbars
   hide the symptom, Windows does not.

   clip rather than hidden: hidden would make this a scroll container,
   which breaks position: sticky anywhere inside it. clip does not. */
.ppsc-ds-page {
  overflow-x: clip;
}

/* ============================================================
   ATOMS
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  /* Most of these components set their transition LATER in the file,
     which would beat a plain `none` here at equal specificity — hence
     !important, the same deliberate exception as the header group
     below. Only applies when the visitor has reduce motion turned on. */
  .ppsc-ds-tag,
  .ppsc-ds-cards-cluster__card,
  .ppsc-ds-buttons-selector__card,
  .ppsc-ds-buttons-selector__card-cta svg,
  .ppsc-ds-buttons-selector__back-link,
  .ppsc-ds-buttons-selector__back-link svg,
  .ppsc-ds-accordion__chevron,
  .ppsc-ds-tabs-selector__chevron,
  .ppsc-ds-tabs-selector__panel,
  .ppsc-ds-tabs-selector__panel-inner {
    transition: none !important;
  }
}

/* --- Tag (pill link) --- */

.ppsc-ds-tag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3xs);
  padding: var(--space-3xs) var(--space-2xs); /* 5px / 9px */
  border-radius: var(--radius-s);
  border: var(--border-s) solid var(--border-emphasis); /* #04A4C8 */
  background: var(--surface-default);
  color: var(--text-link);

  font-family: var(--font-family);
  font-weight: var(--font-semibold);
  font-size: var(--step--2);
  text-transform: var(--ppsc-ds-text-transform-caps);
  line-height: 1.2;
  text-decoration: none;
  /* One line unless the label is wider than the content column (a long
     label on a small phone): then it wraps instead of running off the
     screen. */
  max-width: 100%;
  cursor: pointer;

  transition:
    background-color 0.2s ease,
    color 0.2s ease,
    border-color 0.2s ease;
}

.ppsc-ds-tag:hover {
  background: var(--secondary-hover);
  border-color: var(--secondary-hover);
  color: var(--white);
}

.ppsc-ds-tag__arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 16px;
  height: 16px;
}
.ppsc-ds-tag__arrow svg {
  width: 5px;
  height: 8px;
}

.ppsc-ds-tag:focus-visible {
  outline: 2px solid var(--ppsc-ds-focus-ring);
  outline-offset: 2px;
}

/* On a dark surface (the Hero's Tag/link): white outline and text. */
.ppsc-ds-tag--inverse {
  background: transparent;
  border-color: var(--white);
  color: var(--white);
}
.ppsc-ds-tag--inverse:hover {
  background: var(--white);
  border-color: var(--white);
  color: var(--primary);
}

/* --- Pill (non-interactive label) ---
   Figma "Pill": a rounded label on a 20% tint of the link colour. Used in
   a Card's pills row. Not a link, unlike .ppsc-ds-tag. */
.ppsc-ds-pills {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs);
  margin: 0;
  padding: 0;
  list-style: none;
}
.ppsc-ds-pill {
  display: inline-flex;
  align-items: center;
  height: 32px;
  padding: var(--space-3xs) calc(var(--space-2xs) + var(--space-3xs));
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--secondary) 20%, transparent); /* decorative tint, not a link */
  font-family: var(--font-family);
  font-weight: var(--font-semibold);
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--text-default);
  white-space: nowrap;
}

/* ============================================================
   MOLECULES
   ============================================================ */

/* --- Bullet list --- */

.ppsc-ds-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

/* Bullets sit against the FIRST line, not the vertical middle of the
   item: centring drifts the marker downward as soon as an item wraps
   to two or three lines. The bullet carries the text's font-size and
   line-height so 1lh is exactly one line of the text, and its margin
   centres it on that line at every fluid size. */
.ppsc-ds-list__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2xs);
}

.ppsc-ds-list__bullet {
  flex-shrink: 0;
  font-size: var(--step-0);
  line-height: 1.6;
  margin-top: calc((1lh - 8.44px) / 2);
  width: 8.44px;
  height: 8.44px;
  aspect-ratio: 1 / 1;
  background: var(--tertiary);
  transform: rotate(90deg);
}

.ppsc-ds-list__text {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-default);
}

/* --- Pagination (slider dots + arrows) ---
   Figma's nested "Pagination" component, shared by every slider
   (Testimonial block carousel, Gallery slider). Dots on the left, the
   two round arrows on the right. The dots are built by ppsc-ds.js, as
   the page count depends on the screen width; the row hides itself
   (hidden attribute) when everything fits. --on-dark: white version for
   dark sections. The component sets its own spacing above the row. */
.ppsc-ds-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.ppsc-ds-pagination[hidden] {
  display: none;
}
.ppsc-ds-pagination__dots {
  display: flex;
  gap: var(--ppsc-ds-pagination-dot-gap);
}
.ppsc-ds-pagination__dot {
  width: var(--ppsc-ds-pagination-dot);
  height: var(--ppsc-ds-pagination-dot);
  padding: 0;
  border: 0;
  border-radius: var(--radius-full);
  background: var(--surface-inverse);
  opacity: var(--opacity-50);
  cursor: pointer;
}
.ppsc-ds-pagination__dot[aria-current="true"] {
  opacity: 1;
}
.ppsc-ds-pagination__arrows {
  display: flex;
  gap: var(--space-xs);
}
.ppsc-ds-pagination__arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--ppsc-ds-pagination-arrow-pad);
  border: var(--border-width-emphasis) solid var(--surface-inverse);
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--surface-inverse);
  cursor: pointer;
}
.ppsc-ds-pagination__arrow svg {
  display: block;
}
/* Hover (Figma Arrow, State=Hover): the circle fills, the chevron
   turns white. A disabled arrow has no hover. */
.ppsc-ds-pagination__arrow {
  transition:
    background-color 0.2s ease,
    color 0.2s ease;
}
.ppsc-ds-pagination__arrow:hover:not(:disabled) {
  background: var(--surface-inverse);
  color: var(--text-inverse);
}
.ppsc-ds-pagination__arrow:disabled {
  opacity: var(--opacity-50);
  cursor: default;
}
:is(.ppsc-ds-pagination__dot, .ppsc-ds-pagination__arrow):focus-visible {
  outline: 2px solid var(--ppsc-ds-focus-ring);
  outline-offset: 2px;
}
.ppsc-ds-pagination--on-dark {
  --ppsc-ds-focus-ring: var(--white);
}
.ppsc-ds-pagination--on-dark .ppsc-ds-pagination__dot {
  background: var(--surface-default);
}
.ppsc-ds-pagination--on-dark .ppsc-ds-pagination__arrow {
  border-color: var(--surface-default);
  color: var(--surface-default);
}
.ppsc-ds-pagination--on-dark .ppsc-ds-pagination__arrow:hover:not(:disabled) {
  background: var(--surface-default);
  color: var(--surface-inverse);
}

/* --- Phone links ---
   Real tel: links, and the ones iOS creates on its own from numbers in
   body copy, take the system link colour instead of the browser default
   blue. Element + attribute (0,1,1) is what beats
   Bootstrap's global a / a:hover. Only colour and underline are set,
   which the component link classes (icon grid, tabs contact) already
   match, so their weight and focus styles are untouched. */
a[href^="tel:"],
a[x-apple-data-detectors] {
  color: var(--text-link);
  text-decoration: underline;
}
a[href^="tel:"]:hover,
a[href^="tel:"]:focus,
a[x-apple-data-detectors]:hover,
a[x-apple-data-detectors]:focus {
  color: var(--text-link-hover);
}

/* --- Tooltip --- */

/* A trigger plus a bubble that sits above it. The bubble is always
   placed on top — no flip logic — because every current use is a small
   marker inside body copy with room above it.

   Open state is a data-open attribute on the bubble itself, written by
   ppsc-ds.js, so nothing here reaches through a parent. Closed uses
   display:none rather than opacity: the bubble is referenced by
   aria-describedby and must leave the accessibility tree when it is
   not showing. */
.ppsc-ds-tooltip {
  position: relative;
  display: inline-flex;
  align-items: center;
  /* Sits raised and small against the heading, like a superscript
     marker rather than a second icon on the line. */
  vertical-align: super;
}

/* Keeps the marker on the same line as the word before it: the tooltip
   is an inline-flex box and would otherwise wrap onto a line of its own
   on narrow screens. Wraps the last word + the tooltip. */
.ppsc-ds-tooltip-keep {
  white-space: nowrap;
}

.ppsc-ds-tooltip__trigger {
  display: inline-flex;
  align-items: center;
  padding: 0;
  background: none;
  border: none;
  color: inherit;
  line-height: 0;
  cursor: pointer;
}

.ppsc-ds-tooltip__trigger:focus-visible {
  outline: 2px solid var(--ppsc-ds-focus-ring);
  outline-offset: 2px;
}

.ppsc-ds-tooltip__bubble {
  position: absolute;
  bottom: calc(100% + var(--space-2xs));
  left: 50%;
  /* --ppsc-ds-tooltip-shift is written by ppsc-ds.js when the bubble
     would otherwise run off the side of the screen. */
  translate: calc(-50% + var(--ppsc-ds-tooltip-shift, 0px)) 0;
  z-index: 2;

  width: max-content;
  /* --grid-third is viewport-based and collapses to ~82px on a phone,
     which turned the bubble into a one-word column. The floor keeps it
     readable there, and the viewport cap keeps it on screen. */
  max-width: min(
    max(var(--grid-third), 16rem),
    calc(100vw - 2 * var(--grid-gutter))
  );
  padding: var(--space-2xs);

  background: var(--surface-default);
  border: var(--border-width-default) solid var(--border-default);
  border-radius: var(--radius-m);

  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--text-default);
  text-align: left;
  white-space: normal;
}

.ppsc-ds-tooltip__bubble[data-open="false"] {
  display: none;
}

/* Caret. A rotated square inheriting the bubble's fill and two of its
   borders, so the fill and stroke can never drift from the bubble. */
.ppsc-ds-tooltip__bubble::after {
  content: "";
  position: absolute;
  top: 100%;
  /* Backs out the bubble's shift so the caret stays on the trigger. */
  left: calc(50% - var(--ppsc-ds-tooltip-shift, 0px));
  width: var(--space-2xs);
  height: var(--space-2xs);
  translate: -50% -50%;
  rotate: 45deg;
  background: var(--surface-default);
  border-right: var(--border-width-default) solid var(--border-default);
  border-bottom: var(--border-width-default) solid var(--border-default);
}

/* ============================================================
   ORGANISMS
   ============================================================ */

/* --- Hero ---
   Horizontal gutter + max-width come from .ppsc-ds-section /
   .ppsc-ds-container (applied in markup). This class only owns
   background, overflow, and min-height; the container child owns
   the internal flex layout (content column + image column). */

/* --ppsc-ds-hero-height (LOCAL VALUES, top of file) is the one place
   the hero's height is written. The container matches it and the
   cutout image is capped by it, so they can never drift apart. */
.ppsc-ds-hero {
  --ppsc-ds-focus-ring: var(--white); /* 11:1 on --primary */
  position: relative;
  overflow: hidden;
  background: var(--primary);
  min-height: var(--ppsc-ds-hero-height);
}

.ppsc-ds-hero__container {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  gap: var(--space-2xl); /* text column to image, both image types */
  min-height: var(--ppsc-ds-hero-height);
}

.ppsc-ds-hero__blur {
  position: absolute;
  pointer-events: none;
  z-index: 0;
}
/* Both glows hang from the bottom edge, as in Figma, so a taller hero
   (eyebrow on, long copy) keeps them in place instead of leaving
   Blur 1 behind at the top. overflow: visible lets the blur spill past
   the SVG's own box, so its clipped edge never shows as a hard line;
   the hero's overflow: hidden is what crops it. Up to the SVG's own
   height (451px) Blur 1 stays flush with the top; past that it hangs
   14px below the bottom edge. */
.ppsc-ds-hero__blur svg {
  display: block;
  overflow: visible;
}
.ppsc-ds-hero__blur-1 {
  right: 5%;
  bottom: min(calc(100% - 451px), -14px);
  filter: blur(20px);
}
.ppsc-ds-hero__blur-2 {
  right: -11px;
  bottom: -11px;
  filter: blur(20px);
}

.ppsc-ds-hero:not(.ppsc-ds-hero--show-blur-1) .ppsc-ds-hero__blur-1 {
  display: none;
}
.ppsc-ds-hero:not(.ppsc-ds-hero--show-blur-2) .ppsc-ds-hero__blur-2 {
  display: none;
}

.ppsc-ds-hero__content {
  position: relative;
  z-index: 1;

  width: var(--grid-two-thirds); /* 828px */
  padding: var(--space-2xl-3xl) 0; /* fluid, same as pad-*-3xl */

  display: flex;
  flex-direction: column;
  justify-content: center;
}

.ppsc-ds-hero__header {
  display: flex;
  flex-direction: column;
  gap: var(--space-s); /* 18px */
}

/* Show Eyebrow option (off by default): the Tagline and the Tag/link
   side by side above the heading. Either can be left out; the row
   collapses when both are. */
.ppsc-ds-hero__eyebrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ppsc-ds-hero-eyebrow-gap);
}
.ppsc-ds-hero__eyebrow:not(:has(*)) {
  display: none;
}

.ppsc-ds-hero__tagline {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step--2);
  line-height: 1.2;
  color: var(--white);
}

.ppsc-ds-hero__heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-6);
  line-height: 1.2;
  color: var(--white);
}

.ppsc-ds-hero__subheading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--white);
}

.ppsc-ds-hero__actions {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-s);
  padding-top: var(--space-xl);
}
.ppsc-ds-hero__actions:not(:has(*)) {
  display: none;
}

.ppsc-ds-hero__disclaimer {
  margin: 0;
  padding-top: var(--space-s);
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step--1);
  line-height: 1.2;
  color: var(--white);
}

.ppsc-ds-hero__image {
  position: relative;
  z-index: 1;

  flex: 1;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

/* Cutout: Figma draws the photo at 90.6% of the hero's height, sitting
   on the bottom edge, so it grows with a taller hero instead of staying
   at a fixed size, but never shorter than the standard hero height, so
   a short hero keeps a full-height photo. Absolutely placed so the photo follows the hero's
   height and never sets it (the text column does); max-width keeps a
   very tall hero from pushing it wider than its column. */
.ppsc-ds-hero__image img {
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  display: block;
  height: max(90.6%, min(100%, var(--ppsc-ds-hero-height)));
  max-width: 100%;
  width: auto;
  object-fit: contain;
  object-position: bottom center;
}

.ppsc-ds-hero:not(.ppsc-ds-hero--show-image) .ppsc-ds-hero__image,
.ppsc-ds-hero__image:not(:has(img)) {
  display: none;
}

/* Image type = Contained: a regular photo in a rounded frame instead
   of a cutout. Fills the image column, inset from the top and bottom
   (the container's gap spaces it off the text column). Default (no
   modifier) is Cutout. The photo is absolutely placed so its own
   height never stretches the hero; the text column alone sets the
   height. */
.ppsc-ds-hero--contained .ppsc-ds-hero__image img {
  position: absolute;
  top: var(--space-xl);
  bottom: auto;
  left: 0;
  transform: none;
  width: 100%;
  height: calc(100% - 2 * var(--space-xl));
  max-height: none;
  object-fit: cover;
  object-position: center;
  border-radius: var(--radius-m);
}

/* --- Highlight card ---
   Horizontal gutter comes from .ppsc-ds-section (applied in markup).
   __container caps + centers at the shared content max-width;
   __inner is the visible boxed card itself, at grid-whole (1260px). */

.ppsc-ds-highlight-card {
  /* Naked organism: surface is owned by the wrapping .ppsc-ds-section
     (--surface-default / --surface-neutral / --surface-subtle); vertical spacing is set per
     instance with the .ppsc-ds-pad-top-* / .ppsc-ds-pad-bottom-* utilities. */
}

.ppsc-ds-highlight-card__container {
  display: flex;
  justify-content: center;
}

.ppsc-ds-highlight-card__inner {
  width: 100%;
  max-width: var(--grid-whole); /* 1260px */
  margin-inline: auto;
  background: var(--surface-neutral); /* #F8F7F7 */
  border-radius: var(--radius-l); /* 9px */
  padding: var(--space-s); /* 18px */
  display: flex;
  flex-direction: row;
}

/* The photo is absolutely placed so its own height never sets the
   card's: the text column does, and the photo crops to match it. */
.ppsc-ds-highlight-card__media {
  position: relative;
  flex: 0 0 var(--grid-third); /* 396px */
  border-radius: var(--radius-m); /* 6px */
  overflow: hidden;
}
.ppsc-ds-highlight-card__media img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Opt-in: drop the media on mobile. Used by the Highlight Cards inside
   the Start Your Journey panels, where the photo is decorative and eats
   most of a phone screen above the content. A modifier on the media
   itself, so a card elsewhere on the site keeps its image. The rule
   lives in RESPONSIVE with the other breakpoint work. */

/* Floating container: no card box — content sits directly
   on the section background. Per Figma the text column keeps its
   fixed two-thirds width (828px) with space-2xl between it and the
   image, and the image takes what is left; the text has no inline
   padding because there is no box edge to inset from. */
.ppsc-ds-highlight-card__inner--floating {
  background: none;
  padding: 0;
  gap: var(--space-2xl);
}
.ppsc-ds-highlight-card__inner--floating .ppsc-ds-highlight-card__media {
  flex: 1 1 0;
}
.ppsc-ds-highlight-card__inner--floating .ppsc-ds-highlight-card__content {
  flex: 0 1 var(--grid-two-thirds);
  padding-inline: 0;
}

/* Image = Right: same columns, mirrored. */
.ppsc-ds-highlight-card__inner--media-right {
  flex-direction: row-reverse;
}

/* Theme = Dark: goes on the component root, with the wrapping section
   set to --surface-inverse. Boxed turns the card white; Floating keeps
   no box and switches the text to white. Buttons on a Dark Floating
   card use the -light secondary / tertiary variants in the markup. */
.ppsc-ds-highlight-card--dark .ppsc-ds-highlight-card__inner {
  background: var(--surface-default);
}
.ppsc-ds-highlight-card--dark .ppsc-ds-highlight-card__inner--floating {
  --ppsc-ds-focus-ring: var(--white);
  background: none;
}
.ppsc-ds-highlight-card--dark
  .ppsc-ds-highlight-card__inner--floating
  :is(
    .ppsc-ds-highlight-card__heading,
    .ppsc-ds-highlight-card__subheading,
    .ppsc-ds-highlight-card__text,
    .ppsc-ds-highlight-card__footnote,
    .ppsc-ds-highlight-card__text-below,
    .ppsc-ds-list__text
  ) {
  color: var(--text-inverse);
}

.ppsc-ds-highlight-card__content {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: var(--space-xl) var(--space-2xl); /* 54px / 72px */
}
/* Each child owns its top margin only; this clears the bottom margins
   Bootstrap puts on h2 and p, which would add to every gap. */
.ppsc-ds-highlight-card__content > * {
  margin-bottom: 0;
}

.ppsc-ds-highlight-card__heading {
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-4);
  line-height: 1.2;
  color: var(--text-heading);
}

.ppsc-ds-highlight-card__subheading {
  margin-top: var(--space-m);
  font-family: var(--font-family);
  font-weight: var(--font-semibold);
  font-size: var(--step-1);
  line-height: 1.2;
  color: var(--text-default);
}

/* Show text option: body copy under the subheading. */
.ppsc-ds-highlight-card__text {
  margin-top: var(--space-2xs);
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-default);
}

.ppsc-ds-highlight-card__list {
  margin-top: var(--space-s);
}

/* Whatever comes first after the heading sits space-m below it (Figma
   "Main content" gap), whichever optional fields are switched off. */
.ppsc-ds-highlight-card__heading + :is(
    .ppsc-ds-highlight-card__text,
    .ppsc-ds-highlight-card__list,
    .ppsc-ds-highlight-card__footnote
  ) {
  margin-top: var(--space-m);
}

/* __content is a flex column with no gap — every child owns its own
   top margin (see subheading / list / footnote). Figma gives the
   actions space-xl above them. */
.ppsc-ds-highlight-card__actions {
  margin-top: var(--space-xl);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
}

.ppsc-ds-highlight-card__footnote {
  margin-top: var(--space-s);
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-style: italic;
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--text-default);
}

/* Show text below buttons option. */
.ppsc-ds-highlight-card__text-below {
  margin-top: var(--space-l);
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-default);
}

/* --- Icon grid --- */

.ppsc-ds-icon-grid {
  /* Naked organism: surface is owned by the wrapping .ppsc-ds-section
     (--surface-default / --surface-neutral / --surface-subtle); vertical spacing is set per
     instance with the .ppsc-ds-pad-top-* / .ppsc-ds-pad-bottom-* utilities. */
}

/* Column count is a custom property rather than a hardcoded repeat(),
   so the Detailed (2-3 items) and Compact (2-4 items) variants can set
   it without a rule of their own — and so the tablet/mobile steps below
   are one declaration each. minmax(0, 1fr) rather than 1fr: a bare 1fr
   floors at min-content, which lets a long unbroken word push the
   column wider than its share. */
.ppsc-ds-icon-grid__container {
  --ppsc-ds-icon-grid-cols: 3;
  display: grid;
  grid-template-columns: repeat(var(--ppsc-ds-icon-grid-cols), minmax(0, 1fr));
  align-items: start;
  gap: var(--space-2xl); /* 72px */
}

.ppsc-ds-icon-grid__item {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

.ppsc-ds-icon-grid__header {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--space-xs); /* 14px */
}

.ppsc-ds-icon-grid__icon {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  background: var(--gradient-ppsc);
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

.ppsc-ds-icon-grid__heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-1);
  line-height: 1.2;
  color: var(--text-heading);
}

.ppsc-ds-icon-grid__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  padding-left: var(--space-s);
  border-left: var(--border-m) solid var(--secondary-light);
}

.ppsc-ds-icon-grid__body p {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-default);
}
.ppsc-ds-icon-grid__body strong {
  font-weight: var(--font-bold);
}
/* Detailed: Figma's description and link wrappers each have space-3xs
   above and below, on top of the body's space-3xs gap. */
.ppsc-ds-icon-grid__body:not(.ppsc-ds-icon-grid__body--plain) > p {
  padding-block: var(--space-3xs);
}

/* Figma: a 32px icon box. Icons keep their own size inside it, so every
   item's heading starts at the same place whatever the glyph's size. */
.ppsc-ds-icon-grid__icon-wrap {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ppsc-ds-icon-grid__icon-wrap svg {
  display: block;
  max-width: 100%;
  max-height: 100%;
}

/* Inline link. The :hover colour is reasserted to beat Bootstrap's
   global a:hover. */
.ppsc-ds-icon-grid__link {
  font-weight: var(--font-bold);
  color: var(--text-link);
  text-decoration: underline;
}

.ppsc-ds-icon-grid__link:hover,
.ppsc-ds-icon-grid__link:focus {
  color: var(--text-link-hover);
}
.ppsc-ds-icon-grid__link:focus-visible {
  outline: 2px solid var(--ppsc-ds-focus-ring);
  outline-offset: 2px;
}

/* Tertiary CTA inside a body, on the Detailed variant. The button's
   own padding-block is space-xs and the design calls for space-m above
   the label, so the extra space is added here rather than changing the
   shared button. */
/* Figma: Tertiary No padding, Size M (--tertiary-no-padding in the
   markup), with space-s above. */
.ppsc-ds-icon-grid__cta {
  align-self: flex-start;
  padding: var(--space-s) 0 0;
}
.ppsc-ds-icon-grid__cta .ppsc-ds-btn__arrow svg {
  width: 3.5px;
  height: 7px;
}

/* Compact variant: icon sits above the heading instead of
   beside it, and the body drops the left rule. Modifiers go on the
   elements themselves rather than being reached through a parent — a
   component is styled by its own class alone. */
.ppsc-ds-icon-grid__header--stacked {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-s);
}

.ppsc-ds-icon-grid__body--plain {
  padding-left: 0;
  border-left: 0;
}

/* Compact type and spacing (Figma): 18px heading, 16px text, space-2xs
   between them instead of the item's space-s. */
.ppsc-ds-icon-grid__header--stacked .ppsc-ds-icon-grid__heading {
  font-size: var(--step-0);
}
.ppsc-ds-icon-grid__body--plain p {
  font-size: var(--step--1);
}
.ppsc-ds-icon-grid__header--stacked + .ppsc-ds-icon-grid__body--plain {
  margin-top: calc(var(--space-2xs) - var(--space-s));
}

/* Show section header: an optional heading + text above the grid, in a
   936px column. When it's on, wrap it and the grid in __layout. */
.ppsc-ds-icon-grid__layout {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
}
.ppsc-ds-icon-grid__intro {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  max-width: var(--grid-three-quarters);
}
.ppsc-ds-icon-grid__intro-heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-3);
  line-height: 1.2;
  color: var(--text-heading);
}
.ppsc-ds-icon-grid__intro-text {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-default);
}

/* Column-count variants. The tablet/mobile steps in RESPONSIVE are
   declared later in the file, so they still win — these only set the
   desktop count. */
.ppsc-ds-icon-grid__container--cols-4 {
  --ppsc-ds-icon-grid-cols: 4;
}

.ppsc-ds-icon-grid__container--cols-2 {
  --ppsc-ds-icon-grid-cols: 2;
}

/* Small flat-colour icon that follows heading text (e.g. the footnote
   marker on "100% acceptance*"). Not a gradient PPSC icon. */
.ppsc-ds-icon-grid__heading-icon {
  flex-shrink: 0;
  margin-left: var(--space-3xs);
  vertical-align: middle;
  /* Scales with the heading rather than staying a fixed 19px, so it
     reads as a superscript marker at every size. */
  width: 0.62em;
  height: 0.62em;
}

.ppsc-ds-icon-grid__heading-icon path {
  stroke: var(--surface-accent-strong);
  stroke-width: 0.6px;
}

/* --- Additional links --- */

.ppsc-ds-additional-links {
  /* Naked organism: surface is owned by the wrapping .ppsc-ds-section
     (--surface-default / --surface-neutral / --surface-subtle); vertical spacing is set per
     instance with the .ppsc-ds-pad-top-* / .ppsc-ds-pad-bottom-* utilities.
     border-radius intentionally dropped — a full-width section band has
     square corners. */
}

.ppsc-ds-additional-links__container {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs); /* 14px */
}

/* Centered variant — centers the pill row. Default is left (e.g. the
   Additional Links under the Apply hero). Centered is the opt-in
   (e.g. inside the Get Help grouped band). */
.ppsc-ds-additional-links--centered .ppsc-ds-additional-links__container {
  justify-content: center;
}

/* Headed / multi-column variant — used when a section heading and/or
   small group headings sit above the pills (e.g. "More resources").
   Put this inside __container instead of pills directly; __container's
   own flex-wrap rule above still serves flat, headingless instances
   (e.g. the top-of-page Additional Links) unchanged. */

.ppsc-ds-additional-links__content {
  display: flex;
  flex-direction: column;
  gap: var(--space-l);
  width: 100%;
}

.ppsc-ds-additional-links__heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-3);
  line-height: 1.2;
  color: var(--text-heading);
}

.ppsc-ds-additional-links__groups {
  display: flex;
  flex-direction: row;
  gap: var(--space-xl);
}

.ppsc-ds-additional-links__group {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

.ppsc-ds-additional-links__group-heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-1); /* 21.6px */
  line-height: 1.2;
  color: var(--text-default);
}

/* Show section header with main text: wrap __heading and __text in
   __header (936px max, space-s apart). A bare __heading still works. */
.ppsc-ds-additional-links__header {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  max-width: var(--grid-three-quarters);
}
.ppsc-ds-additional-links__text {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-default);
}

/* Layout = Narrow: the whole component in a centred three-quarters
   column (936px). Full width below 1024px. */
.ppsc-ds-additional-links--narrow .ppsc-ds-additional-links__container {
  max-width: var(--grid-three-quarters);
  margin-inline: auto;
}

.ppsc-ds-additional-links__pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs); /* 14px */
}

/* --- Intro section --- */

.ppsc-ds-intro-section {
  /* Naked organism: surface is owned by the wrapping .ppsc-ds-section
     (--surface-default / --surface-neutral / --surface-subtle); vertical spacing is set per
     instance with the .ppsc-ds-pad-top-* / .ppsc-ds-pad-bottom-* utilities. */
}

/* Downward-arrow icon above the heading, shown by the Show Icon
   option. Gradient-filled circle with a white chevron. */
.ppsc-ds-intro-section__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  align-self: flex-start;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-full);
  background: var(--gradient-ppsc);
  color: var(--text-inverse);
}

.ppsc-ds-intro-section__icon svg {
  display: block;
  width: 16px;
  height: 10px;
}

/* Show Tagline option. Sentence case, not the caps tagline used in
   the mega menu. */
.ppsc-ds-intro-section__tagline {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-semibold);
  font-size: var(--step--1);
  line-height: 1.2;
  color: var(--text-muted);
}

.ppsc-ds-intro-section__heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-5);
  line-height: 1.2;
  color: var(--text-heading);
  overflow-wrap: break-word;
}

.ppsc-ds-intro-section__body {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--text-default);
}

/* Default (Figma "Left Aligned" / Layout=Default): the 936px column
   sits at the left edge of the content width. --centered and --narrow
   center the column instead.
   The container's gap spaces every field (space-s); no child has a
   margin. Fields left out or hidden take no gap. */
.ppsc-ds-intro-section__container {
  max-width: var(--grid-three-quarters); /* 936px */
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

/* Show Buttons container option. Collapses when the CMS leaves it
   empty, so an empty wrapper never adds its top padding. */
.ppsc-ds-intro-section__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-s);
  padding-top: var(--space-s); /* + the container's gap = space-l */
}
.ppsc-ds-intro-section__actions:not(:has(*)) {
  display: none;
}

/* Centered variant (Figma "Main") — centers the column and its text.
   Default is left. */
.ppsc-ds-intro-section--centered {
  text-align: center;
}
.ppsc-ds-intro-section--centered .ppsc-ds-intro-section__container {
  margin-inline: auto;
}
.ppsc-ds-intro-section--centered .ppsc-ds-intro-section__icon {
  align-self: center;
}
.ppsc-ds-intro-section--centered .ppsc-ds-intro-section__actions {
  justify-content: center;
}

/* Narrow layout (Figma "Left Aligned" / Layout=Narrow) — left-aligned
   text in a centered 936px column, so it lines up with a Narrow Media
   Embed or Content block below it. */
.ppsc-ds-intro-section--narrow .ppsc-ds-intro-section__container {
  margin-inline: auto;
}

/* --- Cards cluster ---
   Naked organism: just the card row + cards. Surface is owned by the
   wrapping .ppsc-ds-section; vertical spacing is set per instance with
   the .ppsc-ds-pad-top-* / .ppsc-ds-pad-bottom-* utilities. When placed
   alongside other organisms in one band, they sit as peers inside
   .ppsc-ds-section__stack — never nested or renamed. */

.ppsc-ds-cards-cluster {
  /* Naked organism: surface is owned by the wrapping .ppsc-ds-section
     (--surface-default / --surface-neutral / --surface-subtle); vertical spacing is set per
     instance with the .ppsc-ds-pad-top-* / .ppsc-ds-pad-bottom-* utilities. */
}

/* Same column-count custom property as Icon Grid. A row holds two or
   three cards, so the count is content-driven, not a CSS constant.
   Explicit columns rather than auto-fit: a lone card on the last row
   keeps its column width instead of stretching to full width, which
   would stop reading as a card. */
.ppsc-ds-cards-cluster__row {
  --ppsc-ds-cards-cluster-cols: 3;
  display: grid;
  grid-template-columns: repeat(
    var(--ppsc-ds-cards-cluster-cols),
    minmax(0, 1fr)
  );
  gap: var(--space-l); /* 36px */
  width: 100%;
}

/* Number of cards = 2. The tablet and mobile rules later in the file
   still bring it down to 2 and 1. */
.ppsc-ds-cards-cluster__row--cols-2 {
  --ppsc-ds-cards-cluster-cols: 2;
}

/* Only the card's button(s) are clickable, not the whole card. */
.ppsc-ds-cards-cluster__card {
  text-decoration: none;
  color: inherit;
  background: var(--white);
  border: var(--border-m) solid var(--border-emphasis); /* 1.5px, #04A4C8 */
  border-radius: var(--radius-l); /* 9px */
  padding: var(--space-s); /* 18px */
  display: flex;
  flex-direction: column;
  gap: var(--space-xs); /* 14px */
  transition:
    background 0.2s ease-in-out,
    border-color 0.2s ease-in-out,
    box-shadow 0.2s ease-in-out;
}

/* Hover: --surface-subtle fill, border to --secondary plus Box Shadow S
   (Figma). The date inset turns white so
   it still reads against the tinted fill. Static cards have no hover;
   the :not() also outranks the White theme's card and date fills. */
.ppsc-ds-cards-cluster__card:hover {
  border-color: var(--secondary);
  box-shadow:
    0 2px 2px -10px rgba(0, 0, 0, 0.02),
    0 6px 6px -10px rgba(0, 0, 0, 0.03),
    0 20px 30px -10px rgba(0, 0, 0, 0.04);
}
.ppsc-ds-cards-cluster__card:not(.ppsc-ds-cards-cluster__card--static):hover {
  background: var(--surface-subtle);
}
.ppsc-ds-cards-cluster__card:not(.ppsc-ds-cards-cluster__card--static):hover
  .ppsc-ds-cards-cluster__card-date {
  background: var(--surface-default);
}

.ppsc-ds-cards-cluster__card-heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-2); /* 25.92px */
  line-height: 1.2;
  color: var(--text-heading);
}

.ppsc-ds-cards-cluster__card-description {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-default);
}

/* Figma's inner "Layout" frame: the card's own space-s plus this
   space-xs is the 18px + 14px inset between border and content. No gap of its own — the space above the CTA is
   carried by __card-actions alone, so the two never add up. */
.ppsc-ds-cards-cluster__card-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  padding: var(--space-xs); /* 14px */
}

/* Figma's "Text Group": heading + description only. */
.ppsc-ds-cards-cluster__card-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs); /* 14px */
}

/* Figma's "Links" group: space-m above the CTA, and nothing else
   contributes to that gap. margin-top: auto keeps the CTAs on a shared
   baseline across a row however long each description runs — auto only
   ever adds to the space-m. */
.ppsc-ds-cards-cluster__card-actions {
  margin-top: auto;
  padding-top: var(--space-m); /* 27px */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs);
}

/* --- Card options (component spec, nested "Card" component) ---
   Everything below is optional and left out of the markup when off.
   Media, date and icon are mutually exclusive; icon and tags/tagline
   are mutually exclusive. */

/* Media and date sit above __card-content. The card's own gap is
   space-xs; Figma has space-s under these, so each adds the difference. */
.ppsc-ds-cards-cluster__card-media,
.ppsc-ds-cards-cluster__card-date {
  margin-bottom: calc(var(--space-s) - var(--space-xs));
  border-radius: var(--radius-m);
}
.ppsc-ds-cards-cluster__card-media {
  overflow: hidden;
  aspect-ratio: 16 / 9;
}
.ppsc-ds-cards-cluster__card-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Date block: day, big number, month + year. The inset colour is the
   opposite of the card's, so it reads on either card fill. */
.ppsc-ds-cards-cluster__card-date {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3xs);
  aspect-ratio: 16 / 9;
  padding: 12px 4px;
  background: var(--surface-neutral);
  font-family: var(--font-family);
  line-height: 1.2;
  color: var(--text-default);
  text-align: center;
}
.ppsc-ds-cards-cluster__card-date-day,
.ppsc-ds-cards-cluster__card-date-month {
  font-weight: var(--font-regular);
  font-size: var(--step-1);
}
.ppsc-ds-cards-cluster__card-date-number {
  font-weight: var(--font-bold);
  font-size: var(--step-5);
}

/* Tags + tagline row, above the heading. */
.ppsc-ds-cards-cluster__card-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs);
  margin-bottom: var(--space-s);
}
.ppsc-ds-cards-cluster__card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
}
.ppsc-ds-cards-cluster__card-tagline {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-semibold);
  font-size: var(--step--2);
  font-variant: var(--ppsc-ds-font-variant-small-caps);
  letter-spacing: var(--ppsc-ds-tracking-tagline);
  line-height: 1.2;
  color: var(--text-muted);
}

/* Feature icon (editor picks from the icon library), 48px. */
.ppsc-ds-cards-cluster__card-icon {
  display: block;
  width: 48px;
  height: 48px;
  margin-bottom: var(--space-s);
}
.ppsc-ds-cards-cluster__card-icon svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* "More data": icon + short label pairs under the description. */
.ppsc-ds-cards-cluster__card-details {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin: 0;
  padding: var(--space-2xs) 0 0;
  list-style: none;
}
.ppsc-ds-cards-cluster__card-detail {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  min-width: max-content;
  font-family: var(--font-family);
  font-size: var(--step--1);
  line-height: 1.2;
  color: var(--text-default);
}
.ppsc-ds-cards-cluster__card-detail svg {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
}

/* Pills row: optional label + pills, under the buttons. */
.ppsc-ds-cards-cluster__card-pills {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs);
  padding-top: calc(var(--space-2xs) + var(--space-s));
}
/* The pills wrap beside the label, not under it. */
.ppsc-ds-cards-cluster__card-pills .ppsc-ds-pills {
  flex: 1 1 0;
  min-width: 0;
}
.ppsc-ds-cards-cluster__card-pills-label {
  white-space: nowrap;
  margin: 0;
  font-family: var(--font-family);
  font-size: var(--step--1);
  line-height: 1.2;
  color: var(--text-muted);
}

/* Layout = Horizontal: image or date as a 240px column on the left,
   stretching to the card's height; content on the right. Buttons sit
   space-m apart and the pills label goes above the pills. Stacks back
   to the vertical layout at <=1023px. */
.ppsc-ds-cards-cluster__card--horizontal {
  flex-direction: row;
  gap: var(--space-s);
}
.ppsc-ds-cards-cluster__card--horizontal > .ppsc-ds-cards-cluster__card-media,
.ppsc-ds-cards-cluster__card--horizontal > .ppsc-ds-cards-cluster__card-date {
  flex: 0 0 var(--ppsc-ds-card-media-width);
  align-self: stretch;
  aspect-ratio: auto;
  min-height: var(--ppsc-ds-card-media-min-height);
  margin-bottom: 0;
}
.ppsc-ds-cards-cluster__card--horizontal .ppsc-ds-cards-cluster__card-content {
  flex: 1 1 0;
  min-width: 0;
}
.ppsc-ds-cards-cluster__card--horizontal .ppsc-ds-cards-cluster__card-actions {
  gap: var(--space-m);
}
.ppsc-ds-cards-cluster__card--horizontal .ppsc-ds-cards-cluster__card-pills {
  flex-direction: column;
  align-items: flex-start;
  padding-top: calc(var(--space-m) + var(--space-s));
}
.ppsc-ds-cards-cluster__card--horizontal .ppsc-ds-cards-cluster__card-pills .ppsc-ds-pills {
  flex: none;
  width: 100%;
}

/* Stroke: Accent is the default. Neutral is for secondary cards. Static
   cards (no link, no buttons) have no stroke and no hover. */
.ppsc-ds-cards-cluster__card--neutral {
  border-color: var(--border-default);
}
.ppsc-ds-cards-cluster__card--static,
.ppsc-ds-cards-cluster__card--static:hover {
  border-color: transparent;
  box-shadow: none;
}

/* Theme. Light (the default) and Dark: white cards, on a
   --surface-neutral or --surface-inverse band. White: the band is
   white, so the cards turn --surface-neutral and the date inset white. */
.ppsc-ds-cards-cluster--white .ppsc-ds-cards-cluster__card {
  background: var(--surface-neutral);
}
.ppsc-ds-cards-cluster--white .ppsc-ds-cards-cluster__card-date {
  background: var(--surface-default);
}
/* --- Media embed --- */

.ppsc-ds-media-embed {
  /* Naked organism: surface is owned by the wrapping .ppsc-ds-section
     (--surface-default / --surface-neutral / --surface-subtle); vertical spacing is set per
     instance with the .ppsc-ds-pad-top-* / .ppsc-ds-pad-bottom-* utilities. */
}

.ppsc-ds-media-embed__container {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs); /* 14px, Figma media → caption */
}

/* Layout = Narrow: a centred three-quarters column (936px), to line up
   with a Narrow Intro Section or the Content component. Default (no
   modifier) is the full content width. */
.ppsc-ds-media-embed--narrow .ppsc-ds-media-embed__container {
  max-width: var(--grid-three-quarters); /* 936px */
  margin-inline: auto;
}

/* Every image and video is 16:9 (component spec, Figma Media). */
.ppsc-ds-media-embed__media {
  position: relative;
  border-radius: var(--radius-m); /* 6px */
  overflow: hidden;
  aspect-ratio: 16 / 9;
}
.ppsc-ds-media-embed__media img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ppsc-ds-media-embed__media iframe {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

.ppsc-ds-media-embed__overlay {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--primary-ultra-dark) 50%, transparent);
  border-radius: inherit;
  pointer-events: none;
}

.ppsc-ds-media-embed__play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 1;
  width: 84px;
  height: 84px;
  border-radius: var(--radius-full);
  background: var(--surface-accent-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.ppsc-ds-media-embed__play svg {
  width: 31px;
  height: 35px;
  margin-left: 4px;
}

.ppsc-ds-media-embed__trigger {
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  background: transparent;
  border: none;
  padding: 0;
  margin: 0;
  cursor: pointer;
}
.ppsc-ds-media-embed__trigger:focus-visible {
  outline: 2px solid var(--ppsc-ds-focus-ring);
  outline-offset: -2px;
}

/* Show container: the caption and metadata under the media. A lone
   __metadata straight under __media (as on the Apply page) also works. */
.ppsc-ds-media-embed__info {
  display: flex;
  flex-direction: column;
  gap: var(--ppsc-ds-media-info-gap);
}
.ppsc-ds-media-embed__caption {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step--1);
  line-height: 1.2;
  color: var(--text-muted);
}

.ppsc-ds-media-embed__metadata {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--space-2xs);
}
/* Any 24px library icon (the editor picks one to match the text). */
.ppsc-ds-media-embed__metadata svg {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
}
.ppsc-ds-media-embed__metadata span {
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.2;
  color: var(--text-default);
}

/* --- CTA banner --- */

/* Naked organism: no background or vertical padding of its own. The
   band colour comes from the wrapping .ppsc-ds-section surface (Teal =
   --surface-accent-strong, White = --surface-default) and spacing from
   the .ppsc-ds-pad-* utilities. The theme lives on the card only:
   __card (white, on a teal band), __card--white (white + stroke) and
   __card--gradient. */

.ppsc-ds-cta-banner__container {
  display: flex;
  justify-content: center;
}

.ppsc-ds-cta-banner__card {
  width: 100%;
  max-width: var(--grid-whole); /* 1260px */
  min-height: var(--grid-quarter); /* 288px */
  padding: var(--space-s); /* 18px */
  border-radius: var(--radius-l); /* 9px */
  background: var(--surface-default);
  display: flex;
  justify-content: center;
  align-items: flex-start;
}

/* White theme: a white fill with a neutral stroke rather than the
   teal band's fill-only card. The radius is --radius-l (9px),
   inherited from the base card rule.

   Declared AFTER .ppsc-ds-cta-banner__card on purpose: single classes,
   so source order decides. */
.ppsc-ds-cta-banner__card--white {
  background: var(--surface-default);
  border: var(--border-width-emphasis) solid var(--border-default);
}

.ppsc-ds-cta-banner__media {
  border-radius: var(--radius-m);
  overflow: hidden;
  width: var(--grid-quarter);
  height: 100%;
}
.ppsc-ds-cta-banner__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ppsc-ds-cta-banner__content {
  flex: 1 0 0;
  align-self: stretch;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  gap: var(--space-s);
  padding: var(--space-m) var(--space-l);
}

.ppsc-ds-cta-banner__heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-3);
  line-height: 1.2;
  color: var(--text-heading);
}

.ppsc-ds-cta-banner__body {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--text-default);
}

/* Simple variant with Show image set to No. The card stacks and
   centres, and takes the padding itself (space-xl / space-2xl, Figma)
   because there is no media column to sit beside.

   min-height is cleared here, not on the base rule: on the with-media
   variant the media column is height:100%, so the card's min-height is
   what gives it a height to fill. */
.ppsc-ds-cta-banner__card--no-media {
  min-height: 0;
  flex-direction: column;
  align-items: center;
  flex-shrink: 0;
  padding: var(--space-xl) var(--space-2xl);
}

.ppsc-ds-cta-banner__content--centered {
  align-items: center;
  text-align: center;
  /* Padding lives on the card in this variant, not here. */
  padding: 0;
}

/* Figma puts space-l between the body and the button. __content already
   contributes space-s from its own gap, so only the difference is added
   here — otherwise the two would sum to space-xl. */
.ppsc-ds-cta-banner__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  margin-top: calc(var(--space-l) - var(--space-s));
}
.ppsc-ds-cta-banner__content--centered .ppsc-ds-cta-banner__actions {
  justify-content: center;
}

/* Show slot option (off by default): a row of checkmark highlights
   under the text, e.g. "Free application · No test scores required".
   Not available on Bottom fixed. */
.ppsc-ds-cta-banner__slot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-l);
  margin: 0;
  padding: 0;
  list-style: none;
}
.ppsc-ds-cta-banner__content--centered .ppsc-ds-cta-banner__slot {
  justify-content: center;
}
.ppsc-ds-cta-banner__slot-item {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.2;
  color: var(--text-default);
}
.ppsc-ds-cta-banner__slot-item svg {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
}

/* Nothing left behind when the CMS leaves a container empty. */
.ppsc-ds-cta-banner__actions:not(:has(*)),
.ppsc-ds-cta-banner__slot:not(:has(*)),
.ppsc-ds-cta-banner__media:not(:has(img)) {
  display: none;
}

/* Photograph theme: an editor-uploaded photo fills the band behind the
   white card, under a 70% dark overlay. The photo is a real <img>
   (an editable field, with alt text) rather than a CSS background.
   Goes on the wrapping section in place of a surface class; the card
   inside is the same white no-media card as the Teal theme. If no
   photo is set, the band falls back to the overlay colour. Overlay is
   --surface-inverse-strong at 70%, per the component doc. */
.ppsc-ds-cta-banner--photo {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: var(--surface-inverse-strong);
}
.ppsc-ds-cta-banner__bg {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ppsc-ds-cta-banner--photo::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--surface-inverse-strong);
  opacity: var(--ppsc-ds-cta-photo-overlay);
}

/* Bottom fixed variant: a slim bar pinned to the bottom of the
   viewport with a short label and one Size S primary button. A
   page-level element, not a section: no wrapper, theme or spacing
   classes. The page needs bottom padding at least the bar's height
   (about 55px) so the bar never covers the last of the content. */
.ppsc-ds-cta-banner--bottom-fixed {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: var(--ppsc-ds-z-bottom-bar);
  background: var(--surface-neutral);
  border-top: var(--border-width-default) solid var(--border-default);
}
/* One row wherever label and button fit. On a phone narrower than
   about 400px they don't, so the button drops under the label rather
   than squeezing the label into three lines. */
.ppsc-ds-cta-banner__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs) var(--space-s);
  padding: var(--space-2xs) var(--space-xl);
}
.ppsc-ds-cta-banner__bar-label {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.2;
  color: var(--text-default);
}

/* ------------------------------------------------------------
   ORGANISM — Buttons selector
   Progressive-disclosure routing, the Buttons Selector. A grid of
   cards; choosing one hides the others and
   reveals that card's panel. The same component nests inside its
   own panel to make the second level, so the JS is scoped per
   instance and needs no special case for depth.

   State lives in attributes on the elements themselves, never on
   an ancestor, so no rule here reaches through a parent:
     __card[data-selected]  — the chosen card
     __card[data-hidden]    — the unchosen cards
     __panel[hidden]        — closed panels (out of the a11y tree)

   Desktop hides the chosen card too and shows its label in the
   back row instead. Mobile keeps the chosen card on screen and
   drops the label. Same mechanism, different presentation — see
   RESPONSIVE.
   ------------------------------------------------------------ */

.ppsc-ds-buttons-selector {
  /* Naked organism: the wrapping .ppsc-ds-section owns surface and
     outer padding. */
}

/* Open state. Figma closes the gap once a panel is showing: the intro
   above the grid goes, and the space above the back row drops from the
   section's own top padding to space-l.

   data-panel-open is written by ppsc-ds.js onto the elements named in
   the component root's data-open-state list, so both rules key on an
   attribute of the element they style — nothing reaches through a
   parent, and an instance that doesn't opt in is untouched.

   Specificity, not source order, is what beats the .ppsc-ds-pad-top-*
   utilities at the end of the file: a class plus an attribute is 0,2,0
   against their 0,1,0. These rules can therefore live here with the
   rest of the component. */
.ppsc-ds-section[data-panel-open="true"] {
  padding-top: var(--space-l);
}

.ppsc-ds-buttons-selector[data-panel-open="true"] {
  padding-top: 0;
}

/* Full-bleed band for a nested level. The level-three section sits
   inside .ppsc-ds-container, so it would otherwise be clipped to the
   content width; this escapes both the container's max-width and the
   section's gutter.

   100vw includes the scrollbar width, so this overflows the viewport by
   that amount on platforms with a classic (space-taking) scrollbar.
   .ppsc-ds-page on <main> clips it — that is a required partner to this
   rule, not an optional extra. */
.ppsc-ds-buttons-selector__band--bleed {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
}

/* Level three is two stacked full-bleed bands rather than one, because
   the back row and the content behind it part company at mobile: on
   desktop both are --surface-neutral and read as a single band, on
   mobile the back row moves onto white while the content keeps the
   neutral fill. One band cannot carry two backgrounds, so the split is
   structural. The back band's padding lives here rather than on
   .ppsc-ds-pad-* utilities because it changes per breakpoint; the steps
   band uses pad-top-2xl / pad-bottom-2xl in the markup. */
.ppsc-ds-buttons-selector__back-band {
  background: var(--surface-neutral);
  padding-top: var(--space-xl);
  padding-bottom: var(--space-m);
}

/* The steps band is the last thing in a level-three panel, and
   the white section padding below it reads as a gap between two
   coloured bands. The band pulls that padding back so it ends flush.
   Coupled to the section carrying ppsc-ds-pad-bottom-3xl — if that
   utility changes on the Buttons selector section, this value changes
   with it (both are the fluid space-2xl-3xl, so they match at every
   width). */
.ppsc-ds-buttons-selector__steps-band {
  margin-bottom: calc(-1 * var(--space-2xl-3xl));
}

.ppsc-ds-buttons-selector__grid {
  --ppsc-ds-buttons-selector-cols: 2;
  display: grid;
  grid-template-columns: repeat(
    var(--ppsc-ds-buttons-selector-cols),
    minmax(0, 1fr)
  );
  gap: var(--space-s);
  max-width: var(--grid-three-quarters);
  margin: auto;
}

/* Level two spans the full content width — the three-quarters cap on
   the base grid is a level-one treatment only. */
.ppsc-ds-buttons-selector__grid--cols-3 {
  --ppsc-ds-buttons-selector-cols: 3;
  max-width: none;
  margin-inline: 0;
}

.ppsc-ds-buttons-selector__card {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  width: 100%;
  margin: 0;
  padding: var(--space-l) var(--space-m) var(--space-m);
  text-align: left;
  text-decoration: none;
  background: var(--surface-default);
  border: var(--border-m) solid var(--border-emphasis);
  border-top-width: var(--border-xl);
  border-radius: var(--radius-l);
  cursor: pointer;
  transition:
    background 0.2s ease-in-out,
    border-color 0.2s ease-in-out,
    box-shadow 0.2s ease-in-out;
}

/* Hover: Surface/Subtle fill, Border/Hover and Box Shadow S (Figma).
   Border/Hover is #0492B2, which is --secondary-hover, not the
   --border-hover token. */
.ppsc-ds-buttons-selector__card:hover {
  background: var(--surface-subtle);
  border-color: var(--secondary-hover);
  box-shadow:
    0 2px 2px -10px rgba(0, 0, 0, 0.02),
    0 6px 6px -10px rgba(0, 0, 0, 0.03),
    0 20px 30px -10px rgba(0, 0, 0, 0.04);
}

.ppsc-ds-buttons-selector__card:focus-visible {
  outline: var(--border-m) solid var(--ppsc-ds-focus-ring);
  outline-offset: 2px;
}

/* Desktop replaces the chosen card with its label in the back row,
   so it is hidden here; MOBILE puts it back (display:flex) and the
   fill below is what marks it as chosen there. */
.ppsc-ds-buttons-selector__card[data-selected="true"] {
  display: none;
  background: var(--surface-subtle);
  border-color: var(--secondary-hover); /* Figma Active: Border/Hover */
}

.ppsc-ds-buttons-selector__card[data-hidden="true"] {
  display: none;
}

.ppsc-ds-buttons-selector__card-heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-1);
  line-height: 1.2;
  color: var(--text-heading);
}

.ppsc-ds-buttons-selector__card-description {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-default);
}

/* margin-top:auto pins the CTA to the bottom of the card, so the
   line sits on a common baseline however tall the description is.
   Figma keeps at least space-m above it; the card's space-xs gap
   already counts toward that, so padding adds the difference. */
.ppsc-ds-buttons-selector__card-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  margin-top: auto;
  padding-top: calc(var(--space-m) - var(--space-xs));
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step--1);
  line-height: 1.2;
  color: var(--text-default);
  /* Figma: Tertiary button, No padding, Size S, so it carries the
     tertiary underline (see ppsc-chrome.css). */
  text-decoration: underline;
  text-decoration-thickness: 0.05em;
  text-underline-offset: 0.3em;
  text-underline-position: from-font;
  text-decoration-color: var(--btn-underline-on-light);
}

/* Figma Tertiary Size S icon: the 16x16 "PPSC Icons" chevron from
   Figma, drawn 1:1 in the markup (not a scaled-down 7x12 glyph). */
.ppsc-ds-buttons-selector__card-cta svg {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  transition: transform 0.2s ease;
}
/* The whole card is the button, so hovering it gives the CTA the
   tertiary button's hover: the arrow steps right (as .ppsc-ds-btn). */
.ppsc-ds-buttons-selector__card:hover .ppsc-ds-buttons-selector__card-cta svg {
  transform: translateX(calc(var(--space-2xs) - var(--space-3xs)));
}

/* Back row. Naked — it sits on white at level two and on
   --surface-neutral at level three, so it never sets a background. */
.ppsc-ds-buttons-selector__back {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  padding-bottom: var(--space-xs);
  border-bottom: var(--border-m) solid var(--border-default);
}

.ppsc-ds-buttons-selector__back-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  padding: 0;
  margin: 0;
  background: none;
  border: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-0); /* Figma: Tertiary Size M */
  line-height: 1.2;
  color: var(--text-default);
  /* Figma: Tertiary button, Size M, No padding, left arrow: tertiary
     underline. */
  text-decoration: underline;
  text-decoration-thickness: 0.05em;
  text-underline-offset: 0.3em;
  text-underline-position: from-font;
  text-decoration-color: var(--btn-underline-on-light);
  cursor: pointer;
}

/* Matches the shared button behaviour: the arrow steps away from the
   label on hover. Not a .ppsc-ds-btn, so it carries its own rule. It
   moves with a transform rather than a growing gap, so the link keeps
   its width and the label beside it never shifts. */
.ppsc-ds-buttons-selector__back-link svg {
  transition: transform 0.2s ease;
}

.ppsc-ds-buttons-selector__back-link:hover svg {
  transform: translateX(calc((var(--space-2xs) - var(--space-3xs)) * -1));
}

.ppsc-ds-buttons-selector__back-link:focus-visible {
  outline: var(--border-m) solid var(--ppsc-ds-focus-ring);
  outline-offset: 2px;
}

.ppsc-ds-buttons-selector__back-link svg {
  flex-shrink: 0;
  box-sizing: border-box;
  width: 16px;
  height: 16px;
  padding: 4px 5.5px; /* 16px Figma icon box around the 5x8 glyph */
}

.ppsc-ds-buttons-selector__back-label {
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-muted);
}

/* ------------------------------------------------------------
   ORGANISM — Step-by-step
   Horizontal variant with the Number marker. The connector is
   drawn on the steps row as a single line behind the markers, so
   it never depends on step count; each marker paints its own
   background over it to punch a hole.
   ------------------------------------------------------------ */

.ppsc-ds-step-by-step {
  /* Naked organism — the section owns surface and outer padding. */
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
}

.ppsc-ds-step-by-step__header {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  max-width: var(--grid-three-quarters); /* 936px, Figma */
}

.ppsc-ds-step-by-step__heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-3);
  line-height: 1.2;
  color: var(--text-heading);
}

.ppsc-ds-step-by-step__intro {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-default);
}

/* Closing line below the steps. Same typography as __intro, but a
   separate class because it is a sibling of __steps rather than part
   of __header — the organism's own space-xl gap separates it. */
.ppsc-ds-step-by-step__outro {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-default);
}

.ppsc-ds-step-by-step__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-s);
  /* space-l above the buttons in total; the header's gap gives space-s. */
  margin-top: calc(var(--space-l) - var(--space-s));
}

/* An <ol>, so Bootstrap's reboot gives it padding-left: 2rem and a
   marker. Both are reset here: the numbers are drawn by __marker, and
   the 32px inset pushed the whole steps grid off the section gutter.
   One equal column per step, so 2, 3 or 4 steps always share the full
   width instead of leaving empty 4-up columns. */
.ppsc-ds-step-by-step__steps {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  column-gap: var(--space-xl);
}

.ppsc-ds-step-by-step__step {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

/* The connector: a line across the marker row, drawn from the centre
   of the marker rightwards so it stops at the last step instead of
   overhanging. */
.ppsc-ds-step-by-step__marker-row {
  position: relative;
  display: flex;
  align-items: center;
}

.ppsc-ds-step-by-step__marker-row::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  width: calc(100% + var(--space-xl));
  height: var(--border-s);
  background: var(--tertiary);
}

/* No connector after the last step. :last-child rather than a
   modifier class, so adding or removing a step in the CMS repeater
   needs no extra class on the new last item. */
.ppsc-ds-step-by-step__step:last-child .ppsc-ds-step-by-step__marker-row::before {
  display: none;
}

/* Gradient ring: two backgrounds, the solid fill clipped to
   padding-box and the gradient to border-box, with a transparent
   border acting as the ring. The opaque fill is also what punches the
   hole in the connector line running behind it. */
.ppsc-ds-step-by-step__marker {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 31px;
  height: 31px;
  padding: 6px;
  border: var(--border-s) solid transparent;
  border-radius: 50%;
  background:
    linear-gradient(var(--surface-default), var(--surface-default)) padding-box,
    var(--gradient-button) border-box;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-1);
  line-height: 1;
  color: var(--text-heading);
}

.ppsc-ds-step-by-step__step-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

/* Heading + tagline pair. The two sit closer together than the
   space-s that __step-body puts between its children, so they get
   their own wrapper with its own class rather than being a bare div
   — every element in the system carries a class of its own. */
.ppsc-ds-step-by-step__step-title {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
}

.ppsc-ds-step-by-step__step-heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-1);
  line-height: 1.2;
  color: var(--text-heading);
}

.ppsc-ds-step-by-step__step-tagline {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-style: italic;
  font-size: var(--step--2);
  line-height: 1.2;
  color: var(--text-default);
}

.ppsc-ds-step-by-step__step-text {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--text-default);
}

/* Step style = Dot: the same ring with a filled dot and no number, for
   steps whose order doesn't matter. All markers in one component use
   the same style. */
.ppsc-ds-step-by-step__marker--dot {
  padding: 0; /* the number's padding would squeeze the 19px dot */
}
.ppsc-ds-step-by-step__marker--dot::after {
  content: "";
  flex-shrink: 0;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background: var(--secondary); /* #037F9B, Figma dot (decorative, not a link) */
}

/* Inline link inside a step's text (Longer content): Bold, link
   colour, underlined. */
.ppsc-ds-step-by-step__link {
  font-weight: var(--font-bold);
  color: var(--text-link);
  text-decoration: underline;
}
.ppsc-ds-step-by-step__link:hover {
  color: var(--text-link-hover);
}
.ppsc-ds-step-by-step__link:focus-visible {
  outline: 2px solid var(--ppsc-ds-focus-ring);
  outline-offset: 2px;
}

/* Variant = Longer content: one centred three-quarters column (936px),
   steps stacked with space-xl between them and a vertical connector
   from each marker down to the next. Suited to long text, links and
   bullet lists inside a step. */
.ppsc-ds-step-by-step--long {
  width: 100%;
  max-width: var(--grid-three-quarters);
  margin-inline: auto;
}
.ppsc-ds-step-by-step--long .ppsc-ds-step-by-step__steps {
  grid-auto-flow: row;
  row-gap: var(--space-xl);
}
.ppsc-ds-step-by-step--long .ppsc-ds-step-by-step__step {
  position: relative;
  flex-direction: row;
  gap: var(--space-xs);
}
.ppsc-ds-step-by-step--long .ppsc-ds-step-by-step__step::before {
  content: "";
  position: absolute;
  top: 31px; /* marker height */
  left: 15px;
  width: var(--border-s);
  height: calc(100% - 31px + var(--space-xl));
  background: var(--tertiary);
}
.ppsc-ds-step-by-step--long .ppsc-ds-step-by-step__step:last-child::before,
.ppsc-ds-step-by-step--long .ppsc-ds-step-by-step__marker-row::before {
  display: none;
}
.ppsc-ds-step-by-step--long .ppsc-ds-step-by-step__marker-row {
  align-items: flex-start;
}
.ppsc-ds-step-by-step--long .ppsc-ds-step-by-step__step-body {
  flex: 1 1 auto;
  min-width: 0;
  gap: var(--space-2xs);
}
.ppsc-ds-step-by-step--long .ppsc-ds-step-by-step__step-body > .ppsc-ds-list {
  margin-top: calc(var(--space-xs) - var(--space-2xs));
}

/* --- Accordion --- */

.ppsc-ds-accordion {
  /* Naked organism: surface is owned by the wrapping .ppsc-ds-section
     (--surface-default / --surface-neutral / --surface-subtle); vertical spacing is set per
     instance with the .ppsc-ds-pad-top-* / .ppsc-ds-pad-bottom-* utilities. */
}

.ppsc-ds-accordion__container {
  display: flex;
  flex-direction: row;
  gap: var(--space-2xl);
}

.ppsc-ds-accordion__sidebar {
  flex: 0 1 clamp(240px, 30vw, 432px);
  min-width: 240px;
}

.ppsc-ds-accordion__heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-4);
  line-height: 1.2;
  color: var(--text-heading);
}

.ppsc-ds-accordion__main {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.ppsc-ds-accordion__item {
  border-bottom: var(--border-width-emphasis) solid var(--border-default); /* 1.5px, #DBD9D6 */
}

.ppsc-ds-accordion__item:first-child {
  border-top: var(--border-width-emphasis) solid var(--border-default);
}

.ppsc-ds-accordion__question {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s); /* 18px */
  padding-block: var(--space-s); /* 18px */
  background: transparent;
  border: none;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-family);
  font-weight: var(--font-semibold);
  font-size: var(--step-1); /* 20.25px */
  line-height: 1.2;
  color: var(--text-default);
}
.ppsc-ds-accordion__question:focus-visible {
  outline: 2px solid var(--ppsc-ds-focus-ring);
  outline-offset: -2px;
}

.ppsc-ds-accordion__chevron {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: rotate(180deg);
  transition: transform 0.2s ease;
}
.ppsc-ds-accordion__chevron svg {
  width: 12px;
  height: 7px;
}
.ppsc-ds-accordion__question[aria-expanded="true"] .ppsc-ds-accordion__chevron {
  transform: rotate(0deg);
}

.ppsc-ds-accordion__answer {
  margin: 0;
  padding-bottom: var(--space-s);
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-default);
}

/* Inline link inside an answer. */
.ppsc-ds-accordion__link {
  font-weight: var(--font-bold); /* inline link rule: Bold + underline */
  color: var(--text-link);
  text-decoration: underline;
}

.ppsc-ds-accordion__link:hover,
.ppsc-ds-accordion__link:focus {
  color: var(--text-link-hover);
}
.ppsc-ds-accordion__link:focus-visible {
  outline: 2px solid var(--ppsc-ds-focus-ring);
  outline-offset: 2px;
}

/* Some answers are a bulleted list plus an actions row rather than a
   single paragraph. Stacking them needs a gap the plain paragraph
   answer has no use for, so it is a modifier rather than a change to
   the base rule. */
.ppsc-ds-accordion__answer--rich {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

/* --- Accordion — split (two-column) variant --- */

.ppsc-ds-accordion--split .ppsc-ds-accordion__container {
  flex-direction: column;
  gap: var(--space-xl);
}

.ppsc-ds-accordion__columns {
  display: flex;
  flex-direction: row;
  gap: var(--space-2xl);
}

.ppsc-ds-accordion__column {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.ppsc-ds-accordion__actions {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--space-s);
}

/* Section header: heading + optional main text. In the sidebar it heads
   the sidebar; in the optional-section-header accordion it sits above the columns,
   capped at three-quarters width (936px). A bare __heading with no
   header wrapper still works, as on the Apply page. */
.ppsc-ds-accordion__header {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}
.ppsc-ds-accordion--split .ppsc-ds-accordion__header {
  max-width: var(--grid-three-quarters);
}
.ppsc-ds-accordion__text {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-default);
}

/* Show Buttons container: the section's own buttons (not the ones inside
   an answer, which are __actions). Under the header in the sidebar; after
   the columns in the Two column variant, where the container's space-xl
   gap spaces it. */
.ppsc-ds-accordion__buttons {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-s);
}
.ppsc-ds-accordion__sidebar .ppsc-ds-accordion__buttons {
  margin-top: var(--space-l);
}

/* Accordion w/optional section header, Variant = One column
   (--one-column, with --split): the header, the questions and the
   buttons share one centred three-quarters column (936px, Figma).
   Only one __column is used. */
.ppsc-ds-accordion--one-column .ppsc-ds-accordion__container > * {
  width: 100%;
  max-width: var(--grid-three-quarters);
  margin-inline: auto;
}

/* Theme = Dark: on the root, with the wrapping section set to
   --surface-inverse. White text, teal dividers. Buttons use the -light
   secondary / tertiary variants in the markup. */
.ppsc-ds-accordion--dark {
  --ppsc-ds-focus-ring: var(--white);
}
.ppsc-ds-accordion--dark
  :is(
    .ppsc-ds-accordion__heading,
    .ppsc-ds-accordion__text,
    .ppsc-ds-accordion__question,
    .ppsc-ds-accordion__answer,
    .ppsc-ds-accordion__link,
    .ppsc-ds-list__text
  ) {
  color: var(--text-inverse);
}
.ppsc-ds-accordion--dark .ppsc-ds-accordion__item,
.ppsc-ds-accordion--dark .ppsc-ds-accordion__item:first-child {
  border-color: var(--border-emphasis);
}

/* --- Two column content --- */

.ppsc-ds-two-column-content {
  /* Naked organism: surface is owned by the wrapping .ppsc-ds-section
     (--surface-default / --surface-neutral / --surface-subtle); vertical spacing is set per
     instance with the .ppsc-ds-pad-top-* / .ppsc-ds-pad-bottom-* utilities. */
}

.ppsc-ds-two-column-content__container {
  display: grid;
  grid-template-columns: 17fr 18fr; /* simplified from 612:648 */
  column-gap: var(--space-2xl); /* 72px */
}

.ppsc-ds-two-column-content__col-1 {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

.ppsc-ds-two-column-content__heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-4);
  line-height: 1.2;
  color: var(--text-heading);
}

.ppsc-ds-two-column-content__body {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-default);
}

.ppsc-ds-two-column-content__col-2 {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
}

.ppsc-ds-two-column-content__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-xs);
}

/* Figma: a 24px icon box. Icons keep their own size inside it (a 24px
   library icon fills it; the page's 17-18px glyphs sit centred), so a
   small glyph is never scaled up. */
.ppsc-ds-two-column-content__icon-wrap {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ppsc-ds-two-column-content__icon-wrap svg {
  display: block;
  max-width: 100%;
  max-height: 100%;
}

.ppsc-ds-two-column-content__item-text {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.ppsc-ds-two-column-content__item-heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-1);
  line-height: 1.2;
  color: var(--text-heading);
}

.ppsc-ds-two-column-content__item-description {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--text-default);
}

/* --- Fast facts --- */

.ppsc-ds-fast-facts {
  /* Naked organism: surface is owned by the wrapping .ppsc-ds-section
     (--surface-default / --surface-inverse); vertical spacing is set per
     instance with the .ppsc-ds-pad-top-* / .ppsc-ds-pad-bottom-* utilities.
     The Photograph theme is the exception: see --photo below. */
}

/* Layout = Sidebar on left: header and stats side by side, in the same
   612 : 648 split as Two column content. */
.ppsc-ds-fast-facts__container {
  display: grid;
  grid-template-columns: 17fr 18fr; /* simplified from 612:648 */
  align-items: start;
  column-gap: var(--space-2xl); /* 72px */
}

/* Layout = Sidebar on top: header above a single row of stats. */
.ppsc-ds-fast-facts--top .ppsc-ds-fast-facts__container {
  grid-template-columns: 1fr;
  row-gap: var(--space-xl); /* 54px */
}
.ppsc-ds-fast-facts--top .ppsc-ds-fast-facts__header {
  max-width: var(--grid-three-quarters); /* 936px */
}

.ppsc-ds-fast-facts__header {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

.ppsc-ds-fast-facts__heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-4);
  line-height: 1.2;
  color: var(--text-heading);
}

.ppsc-ds-fast-facts__body {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--text-default);
}

/* Sidebar on left: two 297px columns (1 / 2 / 4 stats). Sidebar on top:
   one row, every stat the same width (3 / 4 stats). */
.ppsc-ds-fast-facts__stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-xl); /* 54px */
  margin: 0;
  padding: 0;
  list-style: none;
}
.ppsc-ds-fast-facts--top .ppsc-ds-fast-facts__stats {
  grid-template-columns: none;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
}
/* Figma (White): a single stat sits in the right-hand column. */
.ppsc-ds-fast-facts__stat:only-child {
  grid-column: 2;
}
.ppsc-ds-fast-facts--top .ppsc-ds-fast-facts__stat:only-child {
  grid-column: auto;
}

.ppsc-ds-fast-facts__stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding-left: var(--space-s);
  border-left: var(--border-width-emphasis) solid var(--border-emphasis);
}

.ppsc-ds-fast-facts__number {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--ppsc-ds-fast-facts-number-size);
  line-height: 1.2;
  color: var(--text-highlight);
}

.ppsc-ds-fast-facts__label {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--text-default);
}

/* Theme = Dark (wrapper --surface-inverse) and Photograph: white text,
   light green numbers. */
:is(.ppsc-ds-fast-facts--dark, .ppsc-ds-fast-facts--photo)
  :is(
    .ppsc-ds-fast-facts__heading,
    .ppsc-ds-fast-facts__body,
    .ppsc-ds-fast-facts__label
  ) {
  color: var(--text-inverse);
}
:is(.ppsc-ds-fast-facts--dark, .ppsc-ds-fast-facts--photo)
  .ppsc-ds-fast-facts__number {
  color: var(--text-highlight-muted);
}

/* Theme = Photograph: an editor-uploaded photo fills the band under a
   70% dark-navy overlay. Same model as the CTA banner's Photograph
   theme: a real <img> (editable, alt=""), on the section in place of a
   surface class. If no photo is set, the band is the overlay colour. */
.ppsc-ds-fast-facts--photo {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: var(--primary-ultra-dark);
}
.ppsc-ds-fast-facts__bg {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ppsc-ds-fast-facts--photo::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--primary-ultra-dark);
  opacity: var(--ppsc-ds-fast-facts-photo-overlay);
}

/* --- Content --- */

.ppsc-ds-content {
  /* Naked organism: surface is owned by the wrapping .ppsc-ds-section
     (--surface-default / --surface-neutral); vertical spacing is set per
     instance with the .ppsc-ds-pad-top-* / .ppsc-ds-pad-bottom-* utilities.
     Theme = Light also needs ppsc-ds-content--light on the section, so
     the boxes and closed panels flip to white. */
}

/* One centred three-quarters column (936px), for both variants. */
.ppsc-ds-content__inner {
  max-width: var(--grid-three-quarters);
  margin-inline: auto;
}

/* --- Rich text ---
   __body is where the Modern Campus editor's output goes. The editor
   writes plain elements (h2, p, ul, a, hr, …), so they are styled by
   element under the component class. Classed blocks (__box, __alert,
   __quote, __figure, __columns) are inserted as snippets. */

.ppsc-ds-content__body {
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-default);
}
/* The clearfix keeps a floated figure inside the column. */
.ppsc-ds-content__body::after {
  content: "";
  display: table;
  clear: both;
}

/* Flow spacing: 18px between blocks, 36px above a heading, 9px under
   it (14px when a list follows). Bootstrap's own margins are cleared
   first so they never add up. */
/* :where keeps this at (0,1,0) so the flow rules below win. */
.ppsc-ds-content__body :where(h1, h2, h3, h4, h5, h6, p, ul, ol, hr, figure, blockquote) {
  margin: 0;
}
.ppsc-ds-content__body > * + * {
  margin-top: var(--space-s);
}
.ppsc-ds-content__body > :is(h1, h2, h3, h4, h5, h6):not(:first-child) {
  margin-top: var(--space-l);
}
.ppsc-ds-content__body > .ppsc-ds-content__tagline + :is(h1, h2, h3, h4, h5, h6) {
  margin-top: var(--space-s);
}
.ppsc-ds-content__body > :is(h1, h2, h3, h4, h5, h6) + * {
  margin-top: var(--space-2xs);
}
.ppsc-ds-content__body > :is(h1, h2, h3, h4, h5, h6) + :is(ul, ol) {
  margin-top: var(--space-xs);
}

.ppsc-ds-content__body :is(h1, h2, h3, h4, h5, h6) {
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  line-height: 1.2;
  color: var(--text-default);
}
.ppsc-ds-content__body h1 { font-size: var(--step-5); }
.ppsc-ds-content__body h2 { font-size: var(--step-4); }
.ppsc-ds-content__body h3 { font-size: var(--step-3); }
.ppsc-ds-content__body h4 { font-size: var(--step-2); }
.ppsc-ds-content__body h5 { font-size: var(--step-1); }
.ppsc-ds-content__body h6 { font-size: var(--step-0); }

.ppsc-ds-content__tagline {
  font-size: var(--step--1);
  line-height: 1.2;
}
/* Figma sets the paragraphs under Heading One at step 1. */
.ppsc-ds-content__lead {
  font-size: var(--step-1);
}

/* Inline treatments. Buttons inside the body keep their own styles. */
.ppsc-ds-content__body a:not(.ppsc-ds-btn, .ppsc-ds-message) {
  font-weight: var(--font-bold); /* inline link rule: Bold + underline */
  color: var(--text-link);
  text-decoration: underline;
}
.ppsc-ds-content__body a:not(.ppsc-ds-btn, .ppsc-ds-message):is(:hover, :focus) {
  color: var(--text-link-hover);
}
.ppsc-ds-content__body a:not(.ppsc-ds-btn, .ppsc-ds-message):focus-visible {
  outline: 2px solid var(--ppsc-ds-focus-ring);
  outline-offset: 2px;
}
.ppsc-ds-content__body :is(strong, b) {
  font-weight: var(--font-bold);
}
.ppsc-ds-content__body small {
  font-size: var(--step--1);
}
.ppsc-ds-content__body :is(sup, sub) {
  font-size: var(--ppsc-ds-content-sup-size);
}

/* Lists: 9px between items, line height 1.2. Each nested level steps
   in 27px from the one above. The marker box (bullet or number) plus
   the 9px gap is the item's left padding; a nested list pulls back by
   that much, so the step is always --space-m. */
.ppsc-ds-content__body :is(ul, ol) {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding: 0;
  list-style: none;
}
.ppsc-ds-content__body :is(ul, ol) :is(ul, ol) {
  margin-top: var(--space-2xs);
  margin-left: calc(var(--space-m) - var(--ppsc-ds-content-marker) - var(--space-2xs));
}
.ppsc-ds-content__body li {
  position: relative;
  padding-left: calc(var(--ppsc-ds-content-marker) + var(--space-2xs));
  line-height: 1.2;
}

/* Unordered: green squares, 8.44 / 6 / 4px by level, centred on the
   first line. */
.ppsc-ds-content__body ul > li {
  --ppsc-ds-content-marker: var(--ppsc-ds-content-marker-1);
  --ppsc-ds-content-bullet: var(--ppsc-ds-content-bullet-1);
}
.ppsc-ds-content__body ul ul > li {
  --ppsc-ds-content-marker: var(--ppsc-ds-content-marker-2);
  --ppsc-ds-content-bullet: var(--ppsc-ds-content-bullet-2);
}
.ppsc-ds-content__body ul ul ul > li {
  --ppsc-ds-content-marker: var(--ppsc-ds-content-marker-3);
  --ppsc-ds-content-bullet: var(--ppsc-ds-content-bullet-3);
}
.ppsc-ds-content__body ul > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: calc((1lh - var(--ppsc-ds-content-bullet)) / 2);
  width: var(--ppsc-ds-content-bullet);
  height: var(--ppsc-ds-content-bullet);
  background: var(--surface-highlight);
}

/* Ordered: bold step -1 numbers in a 20px right-aligned box.
   01. / a. / i. by level. */
.ppsc-ds-content__body ol {
  counter-reset: ppsc-ds-content-ol;
}
.ppsc-ds-content__body ol > li {
  --ppsc-ds-content-marker: var(--ppsc-ds-content-ol-marker);
  counter-increment: ppsc-ds-content-ol;
}
.ppsc-ds-content__body ol > li::before {
  content: counter(ppsc-ds-content-ol, decimal-leading-zero) ".";
  position: absolute;
  left: 0;
  top: 1px;
  width: var(--ppsc-ds-content-marker);
  text-align: right;
  white-space: nowrap;
  font-weight: var(--font-bold);
  font-size: var(--step--1);
  line-height: 1.2;
}
.ppsc-ds-content__body ol ol > li::before {
  content: counter(ppsc-ds-content-ol, lower-alpha) ".";
}
.ppsc-ds-content__body ol ol ol > li::before {
  content: counter(ppsc-ds-content-ol, lower-roman) ".";
}

/* Divider. Bootstrap's hr is a 25%-opacity currentColor bar. */
.ppsc-ds-content__body hr {
  height: 0;
  border: 0;
  border-top: var(--border-width-default) solid var(--border-default);
  background: none;
  opacity: 1;
}

/* Boxed content and Alert are the nested Message component (see
   --- Message --- below). The Content theme picks the Message theme in
   the markup: White → box --neutral, alert --light; Light → box
   --white, alert --accent (Figma Content frames). */

/* Pull quote: green quote mark beside the quote, which hangs its
   opening mark into the gap. */
.ppsc-ds-content__quote {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr); /* mark, then the quote */
  align-items: center;
  column-gap: var(--space-2xl);
}
.ppsc-ds-content__quote-mark {
  align-self: start;
  padding-block: var(--space-xl);
}
.ppsc-ds-content__quote-mark svg {
  display: block;
}
.ppsc-ds-content__quote-content {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
  padding-block: var(--space-xl);
  line-height: 1.2;
}
.ppsc-ds-content__body .ppsc-ds-content__quote-text {
  font-weight: var(--font-bold);
  font-size: var(--step-3);
  line-height: 1.2;
  color: var(--text-heading);
  text-indent: calc(-1 * var(--ppsc-ds-quote-hang));
}
.ppsc-ds-content__quote-cite {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}
.ppsc-ds-content__quote-name {
  font-weight: var(--font-bold);
}

/* Embedded images — the two Figma shows.

   Text + image: a 5-column grid with 72px gutters; the text takes 3
   columns at step 2 ("larger on purpose", Figma), the image takes 2 and
   stretches to the text's height. On mobile the text comes first and
   the image sits below it at 16:9.

   Centred image: two-thirds wide (828px), 16:9, with an optional muted
   caption 14px below it. */
.ppsc-ds-content__body .ppsc-ds-content__image-text {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  column-gap: var(--space-2xl);
  padding-block: var(--space-m);
}
.ppsc-ds-content__body .ppsc-ds-content__image-text-copy {
  grid-column: span 3;
  align-self: center;
  font-size: var(--step-2);
  line-height: 1.6;
}
/* The image is absolutely placed so its own height never sets the
   row's: the text decides the height, the image fills it. */
.ppsc-ds-content__image-text-media {
  grid-column: span 2;
  position: relative;
  margin: 0;
}
.ppsc-ds-content__image-text-media img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: var(--radius-m);
}

.ppsc-ds-content__body .ppsc-ds-content__figure {
  display: grid;
  gap: var(--space-xs);
  width: 100%;
  max-width: var(--grid-two-thirds);
  margin-inline: auto;
  padding-block: var(--space-m);
}
.ppsc-ds-content__figure img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: var(--ppsc-ds-content-media-ratio);
  object-fit: cover;
  border-radius: var(--radius-m);
}
.ppsc-ds-content__figure figcaption {
  font-size: var(--step--1);
  line-height: 1.2;
  color: var(--text-muted);
}

/* Two column format */
.ppsc-ds-content__body .ppsc-ds-content__columns {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  align-items: start;
  gap: var(--space-xl);
}
.ppsc-ds-content__column > * + * {
  margin-top: var(--space-xs);
}

/* --- Variant = Collapsible content ---
   Bootstrap collapse, same wiring as the Accordion. Each panel is a
   teal-outlined card; a closed panel is filled (light gray on White,
   white on Light). The open panel's body is the same rich text as
   the Default variant. */

.ppsc-ds-content__title {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-2);
  line-height: 1.2;
  color: var(--text-default);
}

.ppsc-ds-content__panels {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}
.ppsc-ds-content__title + .ppsc-ds-content__panels {
  margin-top: var(--space-s);
}

.ppsc-ds-content__panel {
  padding: var(--space-m);
  border: var(--border-width-default) solid var(--border-emphasis);
  border-radius: var(--radius-l);
}
.ppsc-ds-content__panel:has(.ppsc-ds-content__panel-toggle[aria-expanded="false"]) {
  background: var(--surface-neutral);
}
.ppsc-ds-content--light
  .ppsc-ds-content__panel:has(.ppsc-ds-content__panel-toggle[aria-expanded="false"]) {
  background: var(--surface-default);
}

.ppsc-ds-content__panel-heading {
  margin: 0;
}
.ppsc-ds-content__panel-toggle {
  width: 100%;
  display: flex;
  align-items: flex-start;
  gap: var(--space-xs);
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-2);
  line-height: 1.2;
  color: var(--text-default);
}
.ppsc-ds-content__panel-toggle:focus-visible {
  outline: 2px solid var(--ppsc-ds-focus-ring);
  outline-offset: 4px;
}
.ppsc-ds-content__panel-label {
  flex: 1;
  min-width: 0;
}
.ppsc-ds-content__panel-icon,
.ppsc-ds-content__panel-state {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ppsc-ds-content__panel-icon svg,
.ppsc-ds-content__panel-state svg {
  display: block;
}
/* Minus when open, plus when closed. */
.ppsc-ds-content__panel-toggle[aria-expanded="true"] .ppsc-ds-content__panel-plus,
.ppsc-ds-content__panel-toggle[aria-expanded="false"] .ppsc-ds-content__panel-minus {
  display: none;
}
.ppsc-ds-content__panel .ppsc-ds-content__body {
  padding-top: var(--space-2xs);
}
/* Inside an open panel Figma spaces blocks 27px apart (text group →
   heading group → alert → button), keeps paragraphs of one group 18px
   apart, and puts 9px under a heading and between a paragraph and the
   list that follows it. */
.ppsc-ds-content__panel .ppsc-ds-content__body > * + *,
.ppsc-ds-content__panel .ppsc-ds-content__body > :is(h1, h2, h3, h4, h5, h6):not(:first-child) {
  margin-top: var(--space-m);
}
.ppsc-ds-content__panel .ppsc-ds-content__body > p + p {
  margin-top: var(--space-s);
}
.ppsc-ds-content__panel .ppsc-ds-content__body > :is(h1, h2, h3, h4, h5, h6) + *,
.ppsc-ds-content__panel .ppsc-ds-content__body > p + :is(ul, ol) {
  margin-top: var(--space-2xs);
}

/* --- Page header ---
   Self-contained like the Hero: the band colour and its blurs are the
   component's identity (Theme Dark / Light), and the doc locks its
   spacing, so it owns its background and vertical padding. Use the
   section wrapper for the horizontal gutter only, no pad-* classes. */

.ppsc-ds-page-header {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: var(--space-3xl); /* 108px */
  background: var(--surface-inverse);
}
.ppsc-ds-page-header--light {
  background: var(--surface-subtle);
}

/* Each blur is one Figma SVG (blob + 120px Gaussian blur), rotated
   about a point below the band's bottom edge, measured from the
   centre so it sits the same at every width. Leave the <img> out to
   turn a blur off. */
.ppsc-ds-page-header__blur {
  position: absolute;
  z-index: -1;
  max-width: none;
  translate: -50% -50%;
  pointer-events: none;
}
.ppsc-ds-page-header__blur--1 {
  left: calc(50% + var(--ppsc-ds-page-header-blur-1-x));
  top: calc(100% + var(--ppsc-ds-page-header-blur-1-y));
  rotate: 24.49deg;
}
.ppsc-ds-page-header__blur--2 {
  left: calc(50% + var(--ppsc-ds-page-header-blur-2-x));
  top: calc(100% + var(--ppsc-ds-page-header-blur-2-y));
  rotate: -31.33deg;
}

.ppsc-ds-page-header__header {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  max-width: var(--grid-three-quarters); /* 936px */
}

.ppsc-ds-page-header__heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-6);
  line-height: 1.2;
  color: var(--text-inverse);
}

/* pre-wrap keeps the spaced bullets ("10 minutes   •   No fees"). */
.ppsc-ds-page-header__subheading {
  margin: 0;
  max-width: var(--grid-two-thirds); /* 828px */
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-1);
  line-height: 1.6;
  white-space: pre-wrap;
  color: var(--text-inverse);
}

.ppsc-ds-page-header--light .ppsc-ds-page-header__heading {
  color: var(--text-heading);
}
.ppsc-ds-page-header--light .ppsc-ds-page-header__subheading {
  color: var(--text-default);
}

/* --- Testimonial block ---
   Naked organism: the wrapping section owns the surface (White =
   --surface-default, Dark = --surface-inverse + --dark) and the
   vertical padding. It is also the positioning box for the two blurs,
   so the section carries the component class (as Fast facts does). */

.ppsc-ds-testimonial-block {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  --ppsc-ds-testimonial-block-blur-1-x: var(--ppsc-ds-testimonial-block-b1-x);
  --ppsc-ds-testimonial-block-blur-1-y: var(--ppsc-ds-testimonial-block-b1-y);
  --ppsc-ds-testimonial-block-blur-2-x: var(--ppsc-ds-testimonial-block-b2-x);
  --ppsc-ds-testimonial-block-blur-2-y: var(--ppsc-ds-testimonial-block-b2-y);
}
.ppsc-ds-testimonial-block--carousel {
  --ppsc-ds-testimonial-block-blur-1-x: var(--ppsc-ds-testimonial-block-carousel-b1-x);
  --ppsc-ds-testimonial-block-blur-1-y: var(--ppsc-ds-testimonial-block-carousel-b1-y);
  --ppsc-ds-testimonial-block-blur-2-x: var(--ppsc-ds-testimonial-block-carousel-b2-x);
  --ppsc-ds-testimonial-block-blur-2-y: var(--ppsc-ds-testimonial-block-carousel-b2-y);
}

/* Same model as the Page header blurs: one Figma SVG each, rotated
   about a point measured from the band's centre and bottom edge.
   Leave the <img> out to turn a blur off. */
.ppsc-ds-testimonial-block__blur {
  position: absolute;
  z-index: -1;
  max-width: none;
  translate: -50% -50%;
  pointer-events: none;
}
.ppsc-ds-testimonial-block__blur--1 {
  left: calc(50% + var(--ppsc-ds-testimonial-block-blur-1-x));
  top: calc(100% + var(--ppsc-ds-testimonial-block-blur-1-y));
  rotate: -21.33deg;
}
.ppsc-ds-testimonial-block__blur--2 {
  left: calc(50% + var(--ppsc-ds-testimonial-block-blur-2-x));
  top: calc(100% + var(--ppsc-ds-testimonial-block-blur-2-y));
  rotate: -60.96deg;
}

/* Quote, name and role — shared by all three layouts. The opening
   quote mark hangs in the left margin (doc): Safari does it with
   hanging-punctuation, every other browser with a negative indent. */
.ppsc-ds-testimonial-block__quote {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-3);
  line-height: 1.2;
  color: var(--text-heading);
  text-indent: calc(-1 * var(--ppsc-ds-quote-hang));
}
@supports (hanging-punctuation: first) {
  .ppsc-ds-testimonial-block__quote {
    text-indent: 0;
    hanging-punctuation: first;
  }
}
.ppsc-ds-testimonial-block__quote p {
  margin: 0;
}
.ppsc-ds-testimonial-block__cite {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  font-family: var(--font-family);
  font-size: var(--step-0);
  line-height: 1.2;
  font-style: normal;
  color: var(--text-default);
}
.ppsc-ds-testimonial-block__name {
  font-weight: var(--font-bold);
}

.ppsc-ds-testimonial-block__figure {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-l);
}

/* Single no image: quote mark + text in a centred 936px row. */
.ppsc-ds-testimonial-block__single {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr); /* mark, then the quote */
  align-items: center;
  column-gap: var(--space-2xl);
  max-width: var(--grid-three-quarters);
  margin-inline: auto;
}
.ppsc-ds-testimonial-block__mark {
  align-self: stretch;
  padding-block: var(--space-xl);
}
.ppsc-ds-testimonial-block__mark svg {
  display: block;
}
.ppsc-ds-testimonial-block__single .ppsc-ds-testimonial-block__figure {
  padding-block: var(--space-xl);
}

/* Single w/image: the photo takes what is left beside a 828px text
   column, and stretches to its height. */
.ppsc-ds-testimonial-block__with-image {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, var(--grid-two-thirds)); /* photo, text */
  align-items: stretch;
  column-gap: var(--space-2xl);
}
/* The photo is absolutely placed so its own height never sets the
   row's: the text column decides the height, the photo fills it. */
.ppsc-ds-testimonial-block__media {
  position: relative;
  margin: 0;
}
.ppsc-ds-testimonial-block__media img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: var(--radius-m);
}
.ppsc-ds-testimonial-block__with-image .ppsc-ds-testimonial-block__figure {
  justify-content: center;
  padding-block: var(--space-xl);
}

/* Carousel */
.ppsc-ds-testimonial-block__header {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  max-width: var(--grid-three-quarters);
  margin-bottom: var(--space-xl);
}
.ppsc-ds-testimonial-block__heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-5);
  line-height: 1.2;
  color: var(--text-heading);
}
.ppsc-ds-testimonial-block__text {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-default);
}

/* The track scrolls sideways; JS moves it a page at a time and never
   on its own (doc: no auto-advance). Two slides per page on desktop,
   one on mobile. The padding-left gives the first slide's hanging
   quote mark room inside the clip. */
.ppsc-ds-testimonial-block__track {
  display: flex;
  gap: var(--space-2xl);
  margin-block: 0;
  list-style: none;
  overflow-x: auto;
  /* Widen the clip box into the gutter by the hang width, so the first
     slide's opening quote mark isn't cut off; slides still line up
     with the header. */
  --ppsc-ds-testimonial-block-hang: calc(var(--step-2) * var(--ppsc-ds-quote-hang-ratio));
  margin-inline-start: calc(-1 * var(--ppsc-ds-testimonial-block-hang));
  padding-inline-start: var(--ppsc-ds-testimonial-block-hang);
  scroll-padding-inline-start: var(--ppsc-ds-testimonial-block-hang);
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
}
.ppsc-ds-testimonial-block__track::-webkit-scrollbar {
  display: none;
}
.ppsc-ds-testimonial-block__slide {
  --ppsc-ds-testimonial-block-slide: min(var(--ppsc-ds-testimonial-block-slide-width), calc((100% - var(--space-2xl)) / 2));
  flex: 0 0 var(--ppsc-ds-testimonial-block-slide);
  scroll-snap-align: start;
}
/* Two 620px slides + the gap leave 20px of the 1332px row empty. The
   last slide carries that space, so the last page can scroll far
   enough to line its first slide up with the header. */
.ppsc-ds-testimonial-block__slide:last-child {
  margin-inline-end: max(0px, calc(100% - 2 * var(--ppsc-ds-testimonial-block-slide) - var(--space-2xl)));
}
.ppsc-ds-testimonial-block__slide .ppsc-ds-testimonial-block__quote {
  font-size: var(--step-2);
}

.ppsc-ds-testimonial-block__pagination {
  margin-top: var(--space-xl);
}

/* Theme = Dark */
.ppsc-ds-testimonial-block--dark {
  --ppsc-ds-focus-ring: var(--white);
}
.ppsc-ds-testimonial-block--dark
  :is(
    .ppsc-ds-testimonial-block__quote,
    .ppsc-ds-testimonial-block__cite,
    .ppsc-ds-testimonial-block__heading,
    .ppsc-ds-testimonial-block__text
  ) {
  color: var(--text-inverse);
}

/* --- Message (nested component) ---
   A tinted box with an optional icon, heading and text. Used on its own
   by Message section and inside Content (Boxed content, Alert). Its
   theme is set by whatever holds it (component doc: "the section theme
   is the only theme editors choose"):
     --white    --surface-default   (Message section Gray, Content Light box)
     --light    --surface-subtle    (Message section Light, Content alert)
     --neutral  --surface-neutral   (Message section White, Content box)
     --accent   --surface-accent    (Content Light alert)
     --gradient green gradient      (Message section Gradient)
   Font size Small (default): text step -1 / 1.2. --medium: step 0 / 1.6.
   --interactive: the whole box is an <a>, with a teal border and a
   tertiary "button" (a <span>); hovering anywhere moves its arrow. */
.ppsc-ds-message {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
  column-gap: var(--space-xs);
  padding: var(--space-s) var(--space-m) var(--space-s) var(--space-s);
  border-radius: var(--radius-m);
  background: var(--surface-neutral);
  color: var(--text-default);
  font-family: var(--font-family);
}
/* Icon column only when there is an icon ("With icon" off = text only). */
.ppsc-ds-message:has(> .ppsc-ds-message__icon) {
  grid-template-columns: auto minmax(0, 1fr);
}
.ppsc-ds-message--white {
  background: var(--surface-default);
}
.ppsc-ds-message--light {
  background: var(--surface-subtle);
}
.ppsc-ds-message--neutral {
  background: var(--surface-neutral);
}
.ppsc-ds-message--accent {
  background: var(--surface-accent);
}
/* Figma (Theme=Gradient): heading and text both text/default. */
.ppsc-ds-message--gradient {
  background: linear-gradient(
    90deg,
    var(--surface-gradient-stop-1),
    var(--surface-gradient-stop-2)
  );
}
.ppsc-ds-message--gradient .ppsc-ds-message__heading {
  color: var(--text-default);
}

.ppsc-ds-message__icon {
  display: block;
  width: 24px;
  height: 24px;
}
.ppsc-ds-message__text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2xs);
}
.ppsc-ds-message__heading {
  margin: 0;
  font-weight: var(--font-bold);
  font-size: var(--step-1);
  line-height: 1.2;
  color: var(--text-heading);
}
.ppsc-ds-message__body {
  margin: 0;
  font-weight: var(--font-regular);
  font-size: var(--step--1);
  line-height: 1.2;
  color: var(--text-default);
}
.ppsc-ds-message--medium .ppsc-ds-message__body {
  font-size: var(--step-0);
  line-height: 1.6;
}
/* Figma: a further space-2xs above the button (18px from the text). */
.ppsc-ds-message__cta {
  margin-top: var(--space-2xs);
}

/* Interactive: Figma draws the 1.5px stroke inside the box, so the
   padding gives that width back and the box keeps its Figma size. */
.ppsc-ds-message--interactive {
  padding:
    calc(var(--space-s) - var(--border-width-emphasis))
    calc(var(--space-m) - var(--border-width-emphasis))
    calc(var(--space-s) - var(--border-width-emphasis))
    calc(var(--space-s) - var(--border-width-emphasis));
  border: var(--border-width-emphasis) solid var(--border-emphasis);
  text-decoration: none;
}
.ppsc-ds-message--interactive:hover .ppsc-ds-btn--tertiary .ppsc-ds-btn__arrow {
  transform: translateX(calc(var(--space-2xs) - var(--space-3xs)));
}
.ppsc-ds-message--interactive:focus-visible {
  outline: var(--border-m) solid var(--ppsc-ds-focus-ring);
  outline-offset: 2px;
}

/* --- Message section ---
   Naked organism: the wrapping section owns the surface and padding.
   The section theme decides the Message theme (set together in the
   markup, never chosen separately):
     White  wrapper --surface-default + message --neutral
     Light  wrapper --surface-default + message --light
     Gray   wrapper --surface-neutral + message --white
     Gradient wrapper --surface-default + message --gradient
   Layout Narrow centres the message at three-quarters (936px); on
   mobile it is always full width (doc). */
.ppsc-ds-message-section {
  /* Naked organism: see above. */
}
.ppsc-ds-message-section--narrow .ppsc-ds-message {
  max-width: var(--grid-three-quarters);
  margin-inline: auto;
}

/* --- Gallery slider ---
   Naked organism: the wrapping section owns the surface (White =
   --surface-default, Light = --surface-neutral) and the padding.
   A row of photos that scrolls sideways (native scroll-snap, so swiping
   works with no extra code); ppsc-ds.js adds the shared Pagination.
   Desktop: up to four 306px-tall photos fill the row (two photos share
   it, Figma test frame); a fifth and more scroll. Tablet: two at a time.
   Mobile: 260px squares, the next one peeking in from the right.
   Never auto-advances (doc). */
.ppsc-ds-gallery-slider__track {
  display: flex;
  gap: var(--space-l);
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
}
.ppsc-ds-gallery-slider__track::-webkit-scrollbar {
  display: none;
}
.ppsc-ds-gallery-slider__slide {
  flex: 1 0 calc((100% - 3 * var(--space-l)) / 4);
  height: var(--ppsc-ds-gallery-slider-height);
  scroll-snap-align: start;
}
.ppsc-ds-gallery-slider__slide img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: var(--radius-m);
}
.ppsc-ds-gallery-slider__pagination {
  margin-top: var(--space-xl);
}

/* ------------------------------------------------------------
   ORGANISM — Tabs Selector
   Audience-routing component: a horizontal tab bar on desktop,
   an accordion on mobile, sharing ONE set of markup. The
   desktop/mobile switch is done entirely with grid line
   placement (see RESPONSIVE) — the DOM order stays
   button / button / button / panel / panel / panel at every width,
   so the keyboard order never diverges from the visual order.

   The buttons are disclosure triggers (aria-expanded + aria-controls),
   NOT ARIA tabs, even though desktop looks like a tab bar. That's
   deliberate: an ARIA tablist must always have exactly one selected
   tab, which would forbid the mobile accordion's all-closed state.
   Panels are role="region" and open via data-open, not the hidden
   property, so the height transition has something to animate.
   ------------------------------------------------------------ */

.ppsc-ds-tabs-selector {
  /* Naked organism: surface is owned by the wrapping .ppsc-ds-section
     (--surface-default / --surface-neutral / --surface-subtle); vertical spacing is set per
     instance with the .ppsc-ds-pad-top-* / .ppsc-ds-pad-bottom-* utilities. */
}

/* Outer wrapper. Holds the tab bar and the panels in one grid so the
   panels sit on row 2 under the bar on desktop, and interleave between
   the buttons on mobile (see RESPONSIVE) — without duplicating markup. */
.ppsc-ds-tabs-selector__tabs {
  display: grid;
  grid-template-columns: 1fr;
}

/* The tab bar itself. Separate from the wrapper so the rule sits under
   the BUTTONS rather than under the whole component. */
.ppsc-ds-tabs-selector__tablist {
  grid-row: 1;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  gap: var(--space-l);
  border-bottom: var(--border-m) solid var(--border-emphasis);
}

.ppsc-ds-tabs-selector__tab {
  appearance: none;
  margin: 0;
  padding: var(--space-xs) var(--space-m);
  background: none;
  border: 0;
  /* Overlaps the tab bar's own rule so the active underline covers it
     rather than stacking on top of it. */
  border-bottom: var(--border-l) solid transparent;
  margin-bottom: calc(-1 * var(--border-m));
  font-family: var(--font-family);
  /* Semibold in every state (Figma): switching weight on
     the active tab changed its width and made the row jump. Active is
     marked by colour and the underline only. */
  font-weight: var(--font-semibold);
  font-size: var(--step-1);
  line-height: 1.2;
  color: var(--text-default);
  text-align: center;
  cursor: pointer;
}

.ppsc-ds-tabs-selector__tab[aria-expanded="true"] {
  color: var(--text-link);
  border-bottom-color: var(--border-emphasis); /* Figma #04A4C8 */
}

.ppsc-ds-tabs-selector__tab:focus-visible {
  outline: var(--border-m) solid var(--ppsc-ds-focus-ring);
  outline-offset: calc(-1 * var(--border-m));
}

/* Chevron is mobile-only — the accordion affordance. Hidden on
   desktop, where the tab bar itself is the affordance. */
/* The Figma chevron points UP, which is the EXPANDED state, so the
   rotation is inverted from the usual pattern: collapsed is rotated,
   expanded sits at rest. Colour is pinned rather than inherited — the
   tab label turns teal when active but the chevron stays dark. */
.ppsc-ds-tabs-selector__chevron {
  display: none;
  flex-shrink: 0;
  color: var(--surface-inverse-strong);
  transform: rotate(180deg);
  transition: transform 0.2s ease;
}

.ppsc-ds-tabs-selector__tab[aria-expanded="true"]
  .ppsc-ds-tabs-selector__chevron {
  transform: rotate(0deg);
}

/* Desktop is a straight swap — no animation. Sliding a panel open when
   the user clicks a sibling tab reads as an accordion, which is the
   wrong affordance for a tab bar. The 0fr → 1fr height transition is
   scoped to the accordion presentation in RESPONSIVE. */
.ppsc-ds-tabs-selector__panel {
  grid-row: 2;
  grid-column: 1;
  display: none;
}

.ppsc-ds-tabs-selector__panel[data-open="true"] {
  display: block;
}

/* Grid rather than flex so the media column is declared once as a
   track; the tablet stack is then a single grid-template-columns
   override instead of unwinding a width and a flex-shrink guard. */
.ppsc-ds-tabs-selector__card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--grid-third);
  align-items: stretch;
  gap: var(--space-2xl);
  /* space-xl under the tabs; nothing below, so the disclaimer's own
     space-l is the only gap after the panel (Figma). */
  padding: var(--space-xl) 0 0 var(--space-l);
}
/* Show image off for a tab: the text takes the whole row. */
.ppsc-ds-tabs-selector__card:not(:has(.ppsc-ds-tabs-selector__media)) {
  grid-template-columns: minmax(0, 1fr);
}

.ppsc-ds-tabs-selector__content {
  min-width: 0;
  display: flex;
  flex-direction: column;
  /* Figma: centred beside the image, space-s above and below. */
  justify-content: center;
  gap: var(--space-m);
  padding-block: var(--space-s);
}

.ppsc-ds-tabs-selector__row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-l);
}

.ppsc-ds-tabs-selector__label {
  flex-shrink: 0;
  width: 180px;
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-semibold);
  font-size: var(--step--1);
  line-height: 1.2;
  color: var(--text-muted);
  text-transform: var(--ppsc-ds-text-transform-caps);
  font-variant-caps: var(--ppsc-ds-font-variant-small-caps);
  letter-spacing: 0.32px;
}

.ppsc-ds-tabs-selector__body {
  flex: 1 1 auto;
  min-width: 0;
}

.ppsc-ds-tabs-selector__name {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-0);
  line-height: 1.2;
  color: var(--text-default);
}

.ppsc-ds-tabs-selector__contact {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.ppsc-ds-tabs-selector__contact-item {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.2;
  color: var(--text-default);
}

/* Gradient PPSC icons: the fill comes from each SVG's own
   <linearGradient>, not from currentColor, so no colour is set here.
   Each instance carries a UNIQUE gradient id (ppsc-tabs-<icon>-<tab>)
   — the same icon appears in all three panels, and duplicate ids
   would make every copy after the first resolve to the wrong fill.
   Intrinsic width/height are left on the SVGs because the three icons
   are not the same size in Figma (17x13 / 17x17 / 15x18). */
.ppsc-ds-tabs-selector__contact-icon {
  flex-shrink: 0;
}

.ppsc-ds-tabs-selector__contact-label {
  font-weight: var(--font-bold);
}

/* Inline link. The :hover colour is reasserted to beat Bootstrap's
   global a:hover { color: #0a58ca }. */
.ppsc-ds-tabs-selector__contact-link {
  font-weight: var(--font-bold);
  color: var(--text-link);
  text-decoration: underline;
}

.ppsc-ds-tabs-selector__contact-link:hover,
.ppsc-ds-tabs-selector__contact-link:focus {
  color: var(--text-link-hover);
}
.ppsc-ds-tabs-selector__contact-link:focus-visible {
  outline: 2px solid var(--ppsc-ds-focus-ring);
  outline-offset: 2px;
}

.ppsc-ds-tabs-selector__media {
  display: flex;
  padding-right: var(--space-l);
  flex-direction: column;
  justify-content: center;
  align-items: flex-end;
}

.ppsc-ds-tabs-selector__image {
  display: block;
  width: 100%;
  border-radius: var(--radius-m);
  height: var(--ppsc-ds-tabs-media-height);
  object-fit: cover;
}

/* Shared, once per component — a sibling of __tabs, not part of any
   panel, because the disclaimer is a shared content slot rather than
   a per-panel one. It therefore owns the gap between itself and the
   panel above. */
.ppsc-ds-tabs-selector__disclaimer {
  margin: var(--space-l) 0 0;
  padding: var(--space-s) var(--space-m) var(--space-s) var(--space-s);
  background: var(--surface-neutral);
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step--1);
  line-height: 1.2;
  color: var(--text-default);
  text-align: center;
  border-radius: var(--radius-m);
}

/* Light theme: Figma flips the disclaimer to white on the grey section. */
.ppsc-ds-section--surface-neutral .ppsc-ds-tabs-selector__disclaimer {
  background: var(--surface-default);
}

/* ============================================================
   SITE LINK GUARD
   Same as the guard in ppsc-chrome.css: the live site's a:visited /
   a:hover / a:active colours (0,1,1) beat our single-class link
   colours. Each rule repeats one of them as a.<class> in those states,
   in the original order so modifiers still win (--inverse after the
   base). Our own :hover / :focus and context rules (0,2,0) still win.
   ============================================================ */
a.ppsc-ds-tag:where(:visited, :hover, :active) {
  color: var(--text-link);
}
a.ppsc-ds-tag--inverse:where(:visited, :hover, :active) {
  color: var(--white);
}
a.ppsc-ds-icon-grid__link:where(:visited, :hover, :active) {
  color: var(--text-link);
}
a.ppsc-ds-message--interactive:where(:visited, :hover, :active) {
  color: var(--text-default);
}
a.ppsc-ds-step-by-step__link:where(:visited, :hover, :active) {
  color: var(--text-link);
}
a.ppsc-ds-accordion__link:where(:visited, :hover, :active) {
  color: var(--text-link);
}
a.ppsc-ds-tabs-selector__contact-link:where(:visited, :hover, :active) {
  color: var(--text-link);
}

/* --- Program list ---
   Naked organism: the wrapping section owns the surface (White =
   --surface-default, Neutral = --surface-neutral) and the padding.
   A list of links to programs, one per row, with a 1.5px divider
   between rows.
   Two column: a sidebar (heading, text, buttons) beside the list. The
   sidebar uses the Accordion's sidebar width, so at 1440 it is 432px
   and the list 828px (Figma).
   Single column (--single): the list alone, centred at three-quarters
   (936px), with optional buttons under it.
   Each row is one link to the program: the name's link is stretched
   over the whole row, and the row tints on hover (Figma List item,
   State=Hover: --surface-neutral on White, white on Neutral). The
   optional "more data" link sits above the stretched link so it stays
   clickable on its own. */
.ppsc-ds-program-list__container {
  display: grid;
  grid-template-columns: clamp(240px, 30vw, 432px) minmax(0, 1fr);
  align-items: start;
  gap: var(--space-2xl);
}

.ppsc-ds-program-list__heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-4);
  line-height: 1.2;
  color: var(--text-heading);
}
.ppsc-ds-program-list__text {
  margin: var(--space-s) 0 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--text-default);
}

/* Show buttons container: under the sidebar text (Two column), or
   under the list (Single column, "bottom buttons"). */
.ppsc-ds-program-list__buttons {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-s);
}
.ppsc-ds-program-list__sidebar .ppsc-ds-program-list__buttons {
  padding-top: var(--space-l);
}

.ppsc-ds-program-list__list {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ppsc-ds-program-list__item {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-s) var(--space-xs);
  border-radius: var(--radius-m);
  transition: background-color 0.2s ease;
}
/* The divider between rows. Drawn on top of the row so a hovered row's
   rounded tint never bends it. */
.ppsc-ds-program-list__item + .ppsc-ds-program-list__item::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: var(--border-width-emphasis); /* 1.5px */
  background: var(--border-default);
}
.ppsc-ds-program-list__item:hover {
  background: var(--surface-neutral);
}
.ppsc-ds-program-list.ppsc-ds-section--surface-neutral .ppsc-ds-program-list__item:hover {
  background: var(--surface-default);
}

.ppsc-ds-program-list__link {
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-1);
  line-height: 1.2;
  color: var(--text-link);
  text-decoration: none;
}
.ppsc-ds-program-list__link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}
.ppsc-ds-program-list__link:focus-visible {
  outline: none;
}
.ppsc-ds-program-list__link:focus-visible::after {
  outline: 2px solid var(--ppsc-ds-focus-ring);
  outline-offset: 2px;
}

/* Show more data: Figma's List item draws it as a tertiary button at
   step 0 Semibold with no underline (the shared tertiary is Bold and
   underlined), so those two are set here. Above the stretched link. */
.ppsc-ds-program-list__more {
  position: relative;
  z-index: 1;
  font-size: var(--step-0);
  font-weight: var(--font-semibold);
}
.ppsc-ds-program-list__more .ppsc-ds-btn__label {
  text-decoration: none;
}

/* Single column: the list (and the bottom buttons) centred at
   three-quarters, space-xl apart. */
.ppsc-ds-program-list--single .ppsc-ds-program-list__container {
  grid-template-columns: minmax(0, var(--grid-three-quarters));
  justify-content: center;
  gap: var(--space-xl);
}

a.ppsc-ds-program-list__link:where(:visited, :hover, :active) {
  color: var(--text-link);
}

/* --- iFrame ---
   Naked organism: the wrapping section owns the surface (White =
   --surface-default, Neutral = --surface-neutral) and the padding.
   Embeds a page from another site or tool (map, form, virtual tour)
   in a rounded frame. The editor gives a URL and a title; the <iframe>
   loads it live (doc). Figma's gray box with the link icon is only a
   placeholder for that live content.
   Simple: the frame is always 16:9 (doc), never shorter than 200px.
   Default is full content width; Narrow (--narrow) is centred at
   three-quarters (936px).
   Two columns (--two-column): a sidebar (heading, text, quick info box)
   beside the frame, with the Program list's 432 / 828 split at 1440.
   On desktop the frame stretches to the sidebar's height (min 200px);
   on mobile it goes back to 16:9 under the sidebar (doc). */
/* width: 100% stops the 200px minimum from widening the frame through
   the 16:9 ratio on narrow phones; below it the frame keeps 200px. */
.ppsc-ds-iframe__frame {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  min-height: 200px;
  overflow: hidden;
  border-radius: var(--radius-l);
  background: var(--surface-neutral); /* shows only while it loads */
}
.ppsc-ds-iframe__frame iframe {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

.ppsc-ds-iframe--narrow .ppsc-ds-iframe__frame {
  max-width: var(--grid-three-quarters);
  margin-inline: auto;
}

.ppsc-ds-iframe--two-column .ppsc-ds-iframe__container {
  display: grid;
  grid-template-columns: clamp(240px, 30vw, 432px) minmax(0, 1fr);
  gap: var(--space-2xl);
}
.ppsc-ds-iframe--two-column .ppsc-ds-iframe__frame {
  aspect-ratio: auto;
}

.ppsc-ds-iframe__sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--space-l);
}
.ppsc-ds-iframe__header {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}
.ppsc-ds-iframe__heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-3);
  line-height: 1.2;
  color: var(--text-heading);
}
.ppsc-ds-iframe__text {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-regular);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--text-default);
}

/* Quick info box: light gray on White, white on Neutral (Figma). Each
   group is a bold subheading and the shared bullet list, at line
   height 1.2 as in Figma. Groups are split by a 1.5px divider with
   space-m above and below it (Figma). */
.ppsc-ds-iframe__links {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
  padding: var(--space-xs);
  border-radius: var(--radius-m);
  background: var(--surface-neutral);
}
.ppsc-ds-iframe.ppsc-ds-section--surface-neutral .ppsc-ds-iframe__links {
  background: var(--surface-default);
}
.ppsc-ds-iframe__links-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}
.ppsc-ds-iframe__links-group + .ppsc-ds-iframe__links-group {
  padding-top: var(--space-m);
  border-top: var(--border-width-emphasis) solid var(--border-default);
}
.ppsc-ds-iframe__links-heading {
  margin: 0;
  font-family: var(--font-family);
  font-weight: var(--font-bold);
  font-size: var(--step-0);
  line-height: 1.2;
  color: var(--text-default);
}
.ppsc-ds-iframe__links .ppsc-ds-list__bullet,
.ppsc-ds-iframe__links .ppsc-ds-list__text {
  line-height: 1.2;
}
/* The items are plain text; a link sits inside the text as an inline
   link (Figma): Bold + underline in the link colour, as in Content. */
.ppsc-ds-iframe__link {
  font-weight: var(--font-bold);
  color: var(--text-link);
  text-decoration: underline;
}
.ppsc-ds-iframe__link:hover,
.ppsc-ds-iframe__link:focus {
  color: var(--text-link-hover);
}
.ppsc-ds-iframe__link:focus-visible {
  outline: 2px solid var(--ppsc-ds-focus-ring);
  outline-offset: 2px;
}

/* ============================================================
   RESPONSIVE
   Every @media override in the file lives here, grouped by
   breakpoint. Add a new responsive rule to the matching block below,
   not to a @media block inside the component's own section.

   Order matters: SMALL DESKTOP (<=1439.98px), then TABLET
   (<=1023.98px), then MOBILE (<=767.98px). Each narrower range sits
   inside the broader one, so putting it later lets it win any property
   both blocks touch.

   The header breakpoints, LOGO (<=1339.98px) and NAV (<=1279.98px),
   are in ppsc-chrome.css with the header.
   ============================================================ */

/* --- SMALL DESKTOP (≤1439.98px) --- */
@media (max-width: 1439.98px) {
  /* Hero: below 1440 the image column keeps its Figma width
     (1332 − 72 − 828 = 432px, from the grid tokens) and the text column
     takes what is left. Below 1024px the TABLET block stacks the hero
     and hides the image. */
  .ppsc-ds-hero__content {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
  }
  .ppsc-ds-hero__image {
    flex: 0 0
      calc(var(--grid-viewport-max) - var(--space-2xl) - var(--grid-2thirds-max));
  }
}

/* --- TABLET (≤1023.98px) --- */
@media (max-width: 1023.98px) {
  .ppsc-ds-intro-section__container,
  .ppsc-ds-media-embed__container,
  .ppsc-ds-media-embed--narrow .ppsc-ds-media-embed__container,
  .ppsc-ds-step-by-step__header,
  .ppsc-ds-step-by-step--long,
  .ppsc-ds-icon-grid__intro,
  .ppsc-ds-additional-links__header,
  .ppsc-ds-additional-links--narrow .ppsc-ds-additional-links__container,
  .ppsc-ds-cta-banner__card,
  .ppsc-ds-accordion--split .ppsc-ds-accordion__header,
  .ppsc-ds-fast-facts--top .ppsc-ds-fast-facts__header,
  .ppsc-ds-content__inner,
  .ppsc-ds-page-header__header,
  .ppsc-ds-page-header__subheading,
  .ppsc-ds-testimonial-block__single,
  .ppsc-ds-testimonial-block__header,
  .ppsc-ds-message-section--narrow .ppsc-ds-message {
    max-width: 100%;
  }

  .ppsc-ds-highlight-card__content {
    padding: var(--space-s) var(--space-l);
  }
  .ppsc-ds-highlight-card__inner {
    max-width: 100%;
  }

  /* Hero — same rules apply through mobile too, so tablet and mobile
     render identically instead of diverging at 767.98px. */
  .ppsc-ds-hero {
    min-height: unset;
  }
  .ppsc-ds-hero__container {
    flex-direction: column;
    min-height: unset;
  }
  .ppsc-ds-hero__content {
    width: 100%;
  }
  .ppsc-ds-hero__image {
    display: none;
  }
  .ppsc-ds-hero__blur-1 {
    right: -528px;
  }
  .ppsc-ds-hero__blur-2 {
    right: -477px;
  }

  /* Icon grid + Cards cluster — 3 across becomes 2. One declaration
     each, because the count is a custom property (see ORGANISMS). */
  .ppsc-ds-icon-grid__container {
    --ppsc-ds-icon-grid-cols: 2;
  }
  .ppsc-ds-cards-cluster__row {
    --ppsc-ds-cards-cluster-cols: 2;
  }
  /* Cards Cluster: a horizontal card stacks like a vertical one from
     tablet down. At 2 per row the fixed 240px media column leaves the
     text too little room (about 70px at 768). */
  .ppsc-ds-cards-cluster__card--horizontal {
    flex-direction: column;
    gap: var(--space-xs);
  }
  .ppsc-ds-cards-cluster__card--horizontal > .ppsc-ds-cards-cluster__card-media,
  .ppsc-ds-cards-cluster__card--horizontal > .ppsc-ds-cards-cluster__card-date {
    flex: none;
    aspect-ratio: 16 / 9;
    min-height: 0;
    margin-bottom: calc(var(--space-s) - var(--space-xs));
  }

  /* Tabs selector — the media stacks under the content from tablet
     down, not just at mobile. var(--grid-third) is viewport-based, so
     around 780px it computes to roughly 190px and the photo collapses
     while the text column is still carrying its 180px label. Declared
     here (like Hero's stacking) so tablet and mobile render the same. */
  .ppsc-ds-tabs-selector__card {
    grid-template-columns: minmax(0, 1fr);
  }
  .ppsc-ds-tabs-selector__media {
    padding-right: 0;
    align-items: stretch;
  }
  .ppsc-ds-tabs-selector__image {
    height: auto;
    aspect-ratio: 16 / 9;
  }

  /* No-media CTA card tightens to space-m all round from tablet down —
     the desktop space-xl / space-2xl padding eats most of a phone's
     width. Declared at tablet so tablet and mobile match. */
  .ppsc-ds-cta-banner__card--no-media {
    padding: var(--space-m);
  }

  /* Buttons selector — the 3-up level-two grid drops to 2. The
     level-one grid is already 2x2 and stays. */
  .ppsc-ds-buttons-selector__grid--cols-3 {
    --ppsc-ds-buttons-selector-cols: 2;
  }

  .ppsc-ds-buttons-selector__grid {
    max-width: 100%;
  }

  /* Gallery slider: two photos at a time (no tablet frame in Figma). */
  .ppsc-ds-gallery-slider__slide {
    flex-basis: calc((100% - var(--space-l)) / 2);
  }

  /* Fast facts — Sidebar on left stacks the header above the stats; a
     single stat moves back to the left. Sidebar on top wraps to two
     stats per row. No tablet frame in Figma yet. */
  .ppsc-ds-fast-facts__container {
    grid-template-columns: 1fr;
    row-gap: var(--space-xl);
  }
  .ppsc-ds-fast-facts__stat:only-child {
    grid-column: auto;
  }
  .ppsc-ds-fast-facts--top .ppsc-ds-fast-facts__stats {
    grid-template-columns: repeat(2, 1fr);
    grid-auto-flow: row;
  }
}

/* --- MOBILE (≤767.98px) --- */
@media (max-width: 767.98px) {
  /* iFrame — Two columns: the sidebar stacks above the frame
     (space-xl), and the frame goes back to 16:9 (doc). */
  .ppsc-ds-iframe--two-column .ppsc-ds-iframe__container {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-xl);
  }
  .ppsc-ds-iframe--two-column .ppsc-ds-iframe__frame {
    aspect-ratio: 16 / 9;
  }
  .ppsc-ds-iframe--narrow .ppsc-ds-iframe__frame {
    max-width: none;
  }

  /* Program list — the sidebar stacks above the list (space-l, plus
     Figma's space-xs under the sidebar buttons), and each row stacks the
     name over the more-data link, whose arrow moves to the far right. */
  .ppsc-ds-program-list__container {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-l);
  }
  .ppsc-ds-program-list__sidebar .ppsc-ds-program-list__buttons {
    padding-bottom: var(--space-xs);
  }
  .ppsc-ds-program-list__item {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-2xs);
  }
  .ppsc-ds-program-list__more {
    width: 100%;
    justify-content: space-between;
  }

  .ppsc-ds-media-embed__play {
    width: 63px;
    height: 63px;
  }
  .ppsc-ds-media-embed__play svg {
    width: 20px;
    height: 28px;
  }
  /* Highlight card */
  .ppsc-ds-highlight-card__inner {
    flex-direction: column;
    max-width: 100%;
  }
  /* Stacked above the content the media is a banner, not a side
     column, so it takes the same 16:9 ratio as the CTA Banner and the
     Tabs Selector rather than the source image's own proportions. */
  .ppsc-ds-highlight-card__media {
    flex-basis: auto;
    aspect-ratio: 16 / 9;
  }
  .ppsc-ds-highlight-card__content {
    padding: var(--space-m) 0;
  }
  .ppsc-ds-highlight-card__media--hide-mobile {
    display: none;
  }

  /* Accordion One column: full width on mobile. */
  .ppsc-ds-accordion--one-column .ppsc-ds-accordion__container > * {
    max-width: none;
  }

  /* Intro Section: the arrow icon is desktop-only (the component
     doc — "always hidden on mobile"). */
  .ppsc-ds-intro-section__icon {
    display: none;
  }

  /* Hero: space-l above the buttons on mobile (space-xl on desktop). */
  .ppsc-ds-hero__actions {
    padding-top: var(--space-l);
  }

  /* Image = Bottom (mobile only): the image goes under the text. */
  .ppsc-ds-highlight-card__inner--media-bottom {
    flex-direction: column-reverse;
  }
  /* Floating stacks like Boxed: no side gap, full-width text. */
  .ppsc-ds-highlight-card__inner--floating {
    gap: 0;
  }
  .ppsc-ds-highlight-card__inner--floating .ppsc-ds-highlight-card__media,
  .ppsc-ds-highlight-card__inner--floating .ppsc-ds-highlight-card__content {
    flex: 0 0 auto;
  }
  /* Figma mobile: space-l above and below the Floating text. */
  .ppsc-ds-highlight-card__inner--floating .ppsc-ds-highlight-card__content {
    padding-block: var(--space-l);
  }
  /* Figma mobile spacing: space-s under the heading, space-l above the
     buttons, space-m above the text below them. */
  .ppsc-ds-highlight-card__subheading,
  .ppsc-ds-highlight-card__heading + :is(
      .ppsc-ds-highlight-card__text,
      .ppsc-ds-highlight-card__list,
      .ppsc-ds-highlight-card__footnote
    ) {
    margin-top: var(--space-s);
  }
  .ppsc-ds-highlight-card__actions {
    margin-top: var(--space-l);
  }
  .ppsc-ds-highlight-card__text-below {
    margin-top: var(--space-m);
  }

  /* Icon grid + Cards cluster — down to a single column. Figma's mobile
     Detailed: items space-xl apart, space-2xs between heading and body. */
  .ppsc-ds-icon-grid__container {
    --ppsc-ds-icon-grid-cols: 1;
    gap: var(--space-xl);
  }
  .ppsc-ds-icon-grid__header:not(.ppsc-ds-icon-grid__header--stacked)
    + .ppsc-ds-icon-grid__body {
    margin-top: calc(var(--space-2xs) - var(--space-s));
  }
  /* Exception: every Compact grid (2, 3 or 4 items) stays two across on
     mobile, space-l apart, as in Figma's mobile frames. Detailed goes
     to one column. Declared after the rule above, and more specific. */
  .ppsc-ds-icon-grid__container--cols-4,
  .ppsc-ds-icon-grid__container:has(.ppsc-ds-icon-grid__header--stacked) {
    --ppsc-ds-icon-grid-cols: 2;
    gap: var(--space-l);
  }

  /* Additional links */
  .ppsc-ds-additional-links__groups {
    flex-direction: column;
  }
  /* Pills start at the left edge on mobile. Mirrors the centred
     variant's own compound selector so it wins on specificity. */
  .ppsc-ds-additional-links--centered .ppsc-ds-additional-links__container {
    justify-content: flex-start;
  }
  /* Tags space-m apart both ways on mobile, in a group or a flat row. */
  .ppsc-ds-additional-links__container,
  .ppsc-ds-additional-links__pills {
    gap: var(--space-m);
  }

  /* Media embed */
  .ppsc-ds-media-embed__container {
    gap: var(--space-xs);
  }

  /* CTA banner — the card stacks, so the space between the media and
     the content is a gap between two siblings and belongs to the
     parent, not to either child. That also means the no-media variant
     needs no exception: a card with one child has nothing to gap
     against, so the rule simply does nothing there. */
  .ppsc-ds-cta-banner__card {
    flex-direction: column;
    gap: var(--space-m);
    max-width: 100%;
  }
  /* Stacked above the content, the media is a banner rather than a
     column, so it takes the 16:9 ratio the Media Embed already uses
     instead of whatever height the source image happens to have. */
  .ppsc-ds-cta-banner__media {
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
  }
  .ppsc-ds-cta-banner__content {
    padding: 0;
  }
  /* Every CTA Banner reads left-aligned on mobile, centred or not —
     centred text over a narrow measure gives a ragged left edge and
     pushes the buttons off the content's own margin. */
  .ppsc-ds-cta-banner__card--no-media {
    align-items: stretch;
  }
  .ppsc-ds-cta-banner__content--centered {
    align-items: flex-start;
    text-align: left;
  }
  .ppsc-ds-cta-banner__content--centered .ppsc-ds-cta-banner__actions,
  .ppsc-ds-cta-banner__content--centered .ppsc-ds-cta-banner__slot {
    justify-content: flex-start;
  }
  .ppsc-ds-cta-banner__bar {
    padding-inline: var(--grid-gutter);
  }

  /* Accordion — space-l under the heading on mobile, for both the
     sidebar and split variants (Figma). */
  .ppsc-ds-accordion__container,
  .ppsc-ds-accordion--split .ppsc-ds-accordion__container {
    flex-direction: column;
    gap: var(--space-l);
  }
  .ppsc-ds-accordion__sidebar {
    flex-basis: auto;
  }

  /* Accordion — split variant */
  .ppsc-ds-accordion__columns {
    flex-direction: column;
    gap: 0;
  }
  .ppsc-ds-accordion__actions {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-s);
  }
  /* Two column content */
  .ppsc-ds-two-column-content__container {
    grid-template-columns: 1fr;
    row-gap: var(--space-l);
  }
  /* List items space-l apart on mobile (space-xl on desktop). */
  .ppsc-ds-two-column-content__col-2 {
    gap: var(--space-l);
  }

  /* Testimonial block: everything stacks, the quote mark shrinks to
     80px, hanging punctuation is off (doc), one slide per page, and the
     blurs move to the mobile frame's positions. */
  .ppsc-ds-testimonial-block {
    --ppsc-ds-testimonial-block-b1-x: 276.32px;
    --ppsc-ds-testimonial-block-b2-x: 597.62px;
    --ppsc-ds-testimonial-block-carousel-b1-x: 276.32px;
    --ppsc-ds-testimonial-block-carousel-b2-x: 597.62px;
  }
  .ppsc-ds-testimonial-block__quote,
  .ppsc-ds-testimonial-block__slide .ppsc-ds-testimonial-block__quote {
    text-indent: 0;
    hanging-punctuation: none;
  }
  .ppsc-ds-testimonial-block__track {
    margin-inline-start: 0;
    padding-inline-start: 0;
    scroll-padding-inline-start: 0;
  }
  .ppsc-ds-testimonial-block__single,
  .ppsc-ds-testimonial-block__with-image {
    grid-template-columns: 1fr;
    align-items: stretch;
    gap: var(--space-l);
  }
  .ppsc-ds-testimonial-block__mark {
    padding-block: 0;
  }
  .ppsc-ds-testimonial-block__mark svg {
    width: auto;
    height: var(--ppsc-ds-testimonial-block-mark-mobile);
  }
  .ppsc-ds-testimonial-block__single .ppsc-ds-testimonial-block__figure,
  .ppsc-ds-testimonial-block__with-image .ppsc-ds-testimonial-block__figure {
    padding-block: 0;
  }
  .ppsc-ds-testimonial-block__media img {
    position: static;
    height: auto;
    aspect-ratio: var(--ppsc-ds-testimonial-block-media-ratio);
  }
  .ppsc-ds-testimonial-block__with-image .ppsc-ds-testimonial-block__quote {
    font-size: var(--step-2);
  }
  .ppsc-ds-testimonial-block__header {
    margin-bottom: var(--space-l);
  }
  .ppsc-ds-testimonial-block__slide {
    flex-basis: 100%;
  }
  .ppsc-ds-testimonial-block__slide:last-child {
    margin-inline-end: 0;
  }

  /* Gallery slider: 260px squares, the next one peeking in (Figma). */
  .ppsc-ds-gallery-slider__slide {
    flex: 0 0 var(--ppsc-ds-gallery-slider-mobile-size);
    height: var(--ppsc-ds-gallery-slider-mobile-size);
  }

  /* Page header: 54px top and bottom (Figma mobile frame). */
  .ppsc-ds-page-header {
    padding-block: var(--space-xl);
  }

  /* Content: text + image stacks (text first, 16:9 image below), the
     centred image goes full width, the pull quote stacks with a
     smaller mark, and two columns become one. */
  .ppsc-ds-content__body .ppsc-ds-content__image-text {
    grid-template-columns: 1fr;
    row-gap: var(--space-s);
    padding-block: 0;
  }
  .ppsc-ds-content__body .ppsc-ds-content__image-text-copy,
  .ppsc-ds-content__image-text-media {
    grid-column: auto;
  }
  .ppsc-ds-content__image-text-media {
    padding-block: var(--space-xs);
  }
  .ppsc-ds-content__image-text-media img {
    position: static;
    height: auto;
    aspect-ratio: var(--ppsc-ds-content-media-ratio);
  }
  .ppsc-ds-content__body .ppsc-ds-content__figure {
    max-width: none;
    padding-block: var(--space-xs);
  }
  .ppsc-ds-content__quote {
    grid-template-columns: 1fr;
    gap: var(--space-l);
  }
  .ppsc-ds-content__quote-mark {
    padding-block: var(--space-l) 0;
  }
  .ppsc-ds-content__quote-mark svg {
    width: auto;
    height: var(--ppsc-ds-content-quote-mark-mobile);
  }
  .ppsc-ds-content__quote-content {
    padding-block: 0 var(--space-l);
  }
  /* Hanging quote mark is off on mobile (Figma mobile frame). */
  .ppsc-ds-content__body .ppsc-ds-content__quote-text {
    text-indent: 0;
  }
  /* Collapsible panels: 18px padding on mobile (27px on desktop). */
  .ppsc-ds-content__panel {
    padding: var(--space-s);
  }
  .ppsc-ds-content__body .ppsc-ds-content__columns {
    grid-template-columns: 1fr;
    gap: var(--space-s);
  }

  /* Fast facts — Figma mobile frame (Design System, node 8338:16286):
     always header on top, 36px to the stats, stats indented 18px, one
     per row 54px apart, 64px numbers. */
  .ppsc-ds-fast-facts__container,
  .ppsc-ds-fast-facts--top .ppsc-ds-fast-facts__container {
    row-gap: var(--space-l);
  }
  .ppsc-ds-fast-facts__stats,
  .ppsc-ds-fast-facts--top .ppsc-ds-fast-facts__stats {
    grid-template-columns: 1fr;
    grid-auto-flow: row;
    gap: var(--space-xl);
    padding-left: var(--space-s);
  }
  .ppsc-ds-fast-facts__number {
    font-size: var(--ppsc-ds-fast-facts-number-size-mobile);
  }

  .ppsc-ds-cards-cluster__row {
    --ppsc-ds-cards-cluster-cols: 1;
    gap: var(--space-s);
  }

  /* Tabs selector — becomes an accordion.

     FULL-BLEED: the item rules and the open item's fill run edge to
     edge, so the component cancels the section's gutter with a
     negative margin and re-applies it to the tab and the card. No
     width calc is needed — a negative margin-inline on a block-level
     box grows it by exactly that much on its own.

     This is only exact because .ppsc-ds-section pins its padding-inline
     to var(--grid-gutter) at this breakpoint (see above). If that pin
     ever changes, this bleed goes with it.

     display:contents dissolves the tab bar box so its buttons become
     grid items of __tabs directly, letting each button be placed on
     its own row and interleave with the panels. Nothing is removed
     from the DOM — this is a layout-only change. */
  .ppsc-ds-tabs-selector__tablist {
    display: contents;
  }
  /* Figma gives each accordion item a 1.5px rule top AND bottom. Drawn
     as a border-top per button plus one border-bottom on the whole
     container: adjacent items would otherwise double up, and a rule on
     the panel itself would still paint while the panel is collapsed. */
  .ppsc-ds-tabs-selector__tabs {
    border-bottom: var(--border-m) solid var(--border-emphasis);
  }
  /* Bleed __tabs only, not the whole component: the shared disclaimer
     is a sibling of __tabs, so leaving it outside the bleed lets it
     keep the section gutter without needing a counter-margin. */
  .ppsc-ds-tabs-selector__tabs {
    margin-inline: calc(var(--grid-gutter) * -1);
  }
  /* Intro sections read longer on mobile, so the centered variant goes
     left-aligned here. */
  .ppsc-ds-intro-section--centered {
    text-align: left;
  }
  .ppsc-ds-intro-section--centered .ppsc-ds-intro-section__actions {
    justify-content: flex-start;
  }
  .ppsc-ds-tabs-selector__tab {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-s);
    padding-block: var(--space-s);
    padding-inline: var(--grid-gutter);
    text-align: left;
    border-top: var(--border-m) solid var(--border-emphasis);
    border-bottom: 0;
    margin-bottom: 0;
  }
  /* Open item is filled; the fill spans the button and its panel, so
     both carry it. */
  .ppsc-ds-tabs-selector__tab[aria-expanded="true"],
  .ppsc-ds-tabs-selector__panel[data-open="true"] {
    background: var(--surface-neutral);
  }
  .ppsc-ds-tabs-selector__chevron {
    display: block;
  }
  /* Animated open/close — accordion only. The panel becomes a one-row
     grid collapsed to 0fr; transitioning to 1fr animates to the
     content's natural height without hardcoding a pixel value, the
     same mechanism the alert bar uses. It is never display:none here,
     or the transition would have nothing to run on, so visibility
     (delayed until the collapse finishes) is what takes the closed
     content out of the accessibility tree and the tab order. */
  .ppsc-ds-tabs-selector__panel,
  .ppsc-ds-tabs-selector__panel[data-open="true"] {
    display: grid;
  }
  .ppsc-ds-tabs-selector__panel {
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.32s ease;
  }
  .ppsc-ds-tabs-selector__panel[data-open="true"] {
    grid-template-rows: 1fr;
  }
  .ppsc-ds-tabs-selector__panel-inner {
    overflow: hidden;
    visibility: hidden;
    transition: visibility 0s linear 0.32s;
  }
  .ppsc-ds-tabs-selector__panel[data-open="true"]
    .ppsc-ds-tabs-selector__panel-inner {
    visibility: visible;
    transition-delay: 0s;
  }
  /* Explicit rows interleave button → panel → button → panel.
     NOTE the panel indices: with __tablist dissolved, the panels are
     still siblings of a <div class="__tablist">, so :nth-of-type
     counts that div as the first div and the panels are divs 2, 3, 4.
     If the markup around the panels changes, these numbers change. */
  .ppsc-ds-tabs-selector__tab:nth-of-type(1) {
    grid-row: 1;
  }
  .ppsc-ds-tabs-selector__panel:nth-of-type(2) {
    grid-row: 2;
  }
  .ppsc-ds-tabs-selector__tab:nth-of-type(2) {
    grid-row: 3;
  }
  .ppsc-ds-tabs-selector__panel:nth-of-type(3) {
    grid-row: 4;
  }
  .ppsc-ds-tabs-selector__tab:nth-of-type(3) {
    grid-row: 5;
  }
  .ppsc-ds-tabs-selector__panel:nth-of-type(4) {
    grid-row: 6;
  }
  /* Up to 4 tabs (component spec). */
  .ppsc-ds-tabs-selector__tab:nth-of-type(4) {
    grid-row: 7;
  }
  .ppsc-ds-tabs-selector__panel:nth-of-type(5) {
    grid-row: 8;
  }
  .ppsc-ds-tabs-selector__card {
    gap: var(--space-s);
    padding: var(--space-s) var(--grid-gutter);
  }
  /* The disclaimer keeps its own fill, so it is inset rather than bled
     — a full-width grey strip would read as part of the open item. */
  .ppsc-ds-tabs-selector__row {
    flex-direction: column;
    gap: var(--space-xs);
  }
  /* Stacked full width, the panel photo is a banner rather than a
     side column, so it takes the same 16:9 ratio as the other media. */
  .ppsc-ds-tabs-selector__image {
    aspect-ratio: 16 / 9;
  }
  .ppsc-ds-tabs-selector__label {
    width: 100%;
  }

  /* Buttons selector — single column, and the chosen card STAYS on
     screen instead of being replaced by its label in the back row.
     That is the only behavioural difference between the two
     presentations; the state attributes are identical. */
  .ppsc-ds-buttons-selector__grid,
  .ppsc-ds-buttons-selector__grid--cols-3 {
    --ppsc-ds-buttons-selector-cols: 1;
    gap: var(--space-s);
  }
  .ppsc-ds-buttons-selector__card[data-selected="true"] {
    display: flex;
  }
  /* The chosen card is still on screen here, so the back row owns the
     gap between the two. At desktop the card is hidden and there is
     nothing above the row to separate it from. */
  .ppsc-ds-buttons-selector__back {
    margin-top: var(--space-l);
    border-bottom: 0;
  }
  /* Figma mobile: space-xl under the back button before the Highlight
     Card. The row already has space-xs below the button, so the card
     adds the rest. Beats the card's .ppsc-ds-pad-top-m (0,2,0). */
  .ppsc-ds-buttons-selector__back + .ppsc-ds-highlight-card {
    padding-top: calc(var(--space-xl) - var(--space-xs));
  }
  /* The back row sits on white on mobile, with space-2xl of it below
     before the neutral content band starts. The space-l above comes
     from __back's own margin. */
  .ppsc-ds-buttons-selector__back-band {
    background: var(--surface-default);
    padding-top: 0;
    padding-bottom: var(--space-2xl);
  }
  .ppsc-ds-buttons-selector__back-label {
    display: none;
  }

  /* Step-by-step — vertical stack. The connector flips to a line down
     the left, drawn on the step itself so it spans the step's full
     height rather than just the marker row. */
  /* Stacked buttons sit closer together than the side-by-side row, and
     sit further from the intro above them. */
  .ppsc-ds-step-by-step__actions {
    gap: var(--space-s);
  }
  /* space-l between the header (text + buttons) and the steps. */
  .ppsc-ds-step-by-step {
    gap: var(--space-l);
  }

  .ppsc-ds-step-by-step__steps {
    grid-auto-flow: row;
    row-gap: var(--space-l);
  }
  .ppsc-ds-step-by-step__step {
    position: relative;
    flex-direction: row;
    gap: var(--space-s);
  }
  .ppsc-ds-step-by-step__step::before {
    content: "";
    position: absolute;
    top: 0;
    left: calc(var(--space-m) / 2);
    width: var(--border-s);
    height: calc(100% + var(--space-l));
    background: var(--tertiary);
  }
  .ppsc-ds-step-by-step__step:last-child::before {
    display: none;
  }
  .ppsc-ds-step-by-step__marker-row {
    align-items: flex-start;
  }
  .ppsc-ds-step-by-step__marker-row::before {
    display: none;
  }
  .ppsc-ds-step-by-step__step-body {
    flex: 1 1 auto;
    min-width: 0;
  }
}

/* ============================================================
   VERTICAL SPACING UTILITIES — per side, independent
   Single-class utilities that set top OR bottom padding. Used on the
   section wrapper AND on components stacked inside a section band, so
   they are not scoped to .ppsc-ds-section. Each sets only its own side.
   Keep this block LAST in the file (source order wins over organisms).
   ============================================================ */

/* Fluid sizes. xl, 2xl and 3xl use the fluid space pairs from
   ppsc-tokens.css, so there is no mobile step-down here: each one grows
   from its mobile value at 318px to its full Figma value at the 1332px
   container, and holds it above that.
     xl  → --space-l-xl     36px → 54px
     2xl → --space-xl-2xl   54px → 72px
     3xl → --space-2xl-3xl  72px → 108px
   none and l stay fixed (0 / 36px). This covers section padding and the
   gap between blocks stacked inside a section (e.g. intro → cards). */

.ppsc-ds-pad-top-none {
  padding-top: 0;
}
/* Not a section spacing option: only for the space-m gap between two
   components inside one section (Start: back row -> Highlight Card). */
.ppsc-ds-pad-top-m {
  padding-top: var(--space-m);
}
.ppsc-ds-pad-top-l {
  padding-top: var(--space-l);
}
.ppsc-ds-pad-top-xl {
  padding-top: var(--space-l-xl);
}
.ppsc-ds-pad-top-2xl {
  padding-top: var(--space-xl-2xl);
}
.ppsc-ds-pad-top-3xl {
  padding-top: var(--space-2xl-3xl);
}

.ppsc-ds-pad-bottom-none {
  padding-bottom: 0;
}
.ppsc-ds-pad-bottom-l {
  padding-bottom: var(--space-l);
}
.ppsc-ds-pad-bottom-xl {
  padding-bottom: var(--space-l-xl);
}
.ppsc-ds-pad-bottom-2xl {
  padding-bottom: var(--space-xl-2xl);
}
.ppsc-ds-pad-bottom-3xl {
  padding-bottom: var(--space-2xl-3xl);
}
