/* ═══════════════════════════════════════════════════════════════════════════
   Page Sections
   Reusable landing-page sections for Kirby CMS 5+
   ═══════════════════════════════════════════════════════════════════════════

   Ported from the "Landing page design concepts" board (layouts A–P). The board
   pinned every color as a literal; here everything resolves through the site's
   canonical --ds-* tokens (style-lean.css §"CANONICAL DESIGN TOKENS").

   ── What this file deliberately does NOT contain ──────────────────────────

   style-lean.css is the site's design system and already ships the primitives.
   Redefining them here would fork them, so the sections consume them instead:

     Buttons            .btn + .btn-primary / .btn-secondary / .btn-white /
                        .btn--ghost                        (style-lean §07)
     Heading scale      h1–h6 sizes, weights, line-heights (style-lean §03)
     Chips              [data-chip="true"]                 (style-lean §22)
     Form controls      input / label base styling         (style-lean §06)
     Focus rings        a, button, input, select, textarea (style-lean §02)
     Screen-reader text .visually-hidden                   (style-lean §canon)
     External-link mark a[href^="http"]::after             (style-lean §21)
     Dark mode          [data-theme="dark"] --ds-* overrides (style-lean §34)

   What IS here: the section shell (background / container / spacing), the
   section layouts themselves, and the handful of deltas the shared components
   need when they sit on a filled brand panel.

   Because color comes from the tokens, dark mode needs no rules of its own.
   The two exceptions are the surfaces that paint themselves — brand and
   inverted panels — which stay dark in both themes by design.

   Namespace: .ps  ·  Sections: .ps-hero, .ps-cards, .ps-pricing, …
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 1. Local tokens ──────────────────────────────────────────────────────── */

.ps {
  --ps-brand:        var(--ds-brand, #294557);
  --ps-brand-light:  var(--ds-brand-light, #dce5ec);
  --ps-on-brand:     var(--ds-text-on-brand, #ffffff);
  /* The softened foreground for secondary copy on a filled panel.
     The board mixes ~78% toward the panel color, which reads well but lands
     at 6.8:1 in light mode and 6.0:1 in dark (where the brand token flips to a
     light blue and the mix runs the other way). 90% clears 7:1 in both
     directions — 8.6:1 light, 7.1:1 dark — for a barely visible softening. */
  --ps-on-brand-dim: color-mix(in srgb, var(--ps-on-brand) 90%, var(--ps-brand));

  --ps-text:   var(--ds-text-primary, #232323);
  --ps-text-2: var(--ds-text-secondary, #475569);
  --ps-muted:  var(--ds-text-muted, #525252);

  --ps-surface: var(--ds-surface, #ffffff);
  --ps-raised:  var(--ds-surface-raised, #f8fafc);
  --ps-sunken:  var(--ds-surface-sunken, #f1f5f9);

  --ps-border:        var(--ds-border, #e5e7eb);
  --ps-border-strong: var(--ds-border-strong, #d1d5db);
  --ps-focus:         var(--ds-border-focus, #294557);
  --ps-link:          var(--ds-link, #294557);

  /* Text-grade status colors. The --ds-success / --ds-warning / --ds-error
     tokens are the *fill* grades — #059669 is only 3.8:1 on white, so a 13px
     delta set in it would fail. The --*-text grades are the readable pair. */
  --ps-positive: var(--ds-success-text, #065f46);
  --ps-warning:  var(--ds-warning-text, #92400e);
  --ps-negative: var(--ds-error-text, #991b1b);

  /* Solid dots and bars are non-text, so they keep the fill grades. */
  --ps-positive-fill: var(--ds-success, #059669);
  --ps-warning-fill:  var(--ds-warning, #d97706);

  --ps-radius:    var(--ds-radius, 8px);
  --ps-radius-lg: var(--ds-radius-lg, 12px);
  --ps-radius-xl: 16px;

  --ps-shadow:    var(--ds-shadow-sm, 0 1px 2px rgba(15, 23, 42, .05));
  --ps-shadow-lg: var(--ds-shadow-lg, 0 10px 15px -3px rgba(15, 23, 42, .12));

  --ps-mono: var(--ds-font-mono, 'JetBrains Mono', ui-monospace, monospace);

  /* Container widths, matching the board's frames. The site's own .container
     is a single fixed 1200px measure; sections need three. */
  --ps-w-narrow:  720px;
  /* Border-box widths that INCLUDE the 30px gutter, so the content edge lands
     on the same x as style-lean's .container (which puts its 15px gutters
     outside a content-box max-width). 1140 content + 30 gutter = 1170. */
  --ps-w-default: 1170px;
  --ps-w-wide:    1240px;
  --ps-gutter:    clamp(1.25rem, 4vw, 1.75rem);

  /* Grid column count, set per section by the snippets */
  --ps-cols: 3;

  box-sizing: border-box;
  color: var(--ps-text);
}

.ps *,
.ps *::before,
.ps *::after { box-sizing: border-box; }

/* Pages that opt out of dark mode for their sections (blueprint: theme=light) */
.ps-page--light .ps {
  --ps-text: #232323;
  --ps-text-2: #475569;
  --ps-muted: #525252;
  --ps-surface: #ffffff;
  --ps-raised: #f8fafc;
  --ps-sunken: #f1f5f9;
  --ps-border: #e5e7eb;
  --ps-border-strong: #d1d5db;
  color-scheme: light;
}

/* ── 2. Section shell: tone, container, spacing ───────────────────────────── */

/* style-lean sets `section { overflow: hidden }`, which would clip a sticky
   rail; sections opt back out and re-clip only where they paint media. */
.ps {
  position: relative;
  width: 100%;
  overflow: visible;
}

.ps--tone-surface { background: var(--ps-surface); }
.ps--tone-raised  { background: var(--ps-raised); }
.ps--tone-sunken  { background: var(--ps-sunken); }
.ps--tone-none    { background: transparent; }

/* Filled panels paint their own surface, so they carry their own foreground
   pair rather than the page's.
   The brand panel follows the token: in dark mode --ds-brand flips to a LIGHT
   blue and --ds-text-on-brand to near-black, so the panel inverts with it.
   The inverted panel does not — its background is a fixed near-black — so it
   re-points --ps-brand / --ps-on-brand at its own pair. Everything downstream
   (buttons, ticks, score bars) then resolves correctly in both themes without
   a single [data-theme] rule in this file. */
.ps--tone-brand,
.ps--tone-dark {
  --ps-text: var(--ps-on-brand);
  --ps-text-2: var(--ps-on-brand-dim);
  --ps-muted: var(--ps-on-brand-dim);
  --ps-surface: transparent;
  --ps-raised: color-mix(in srgb, var(--ps-on-brand) 8%, transparent);
  --ps-border: color-mix(in srgb, var(--ps-on-brand) 24%, transparent);
  --ps-border-strong: color-mix(in srgb, var(--ps-on-brand) 40%, transparent);
  --ps-link: var(--ps-on-brand);
  --ps-focus: var(--ps-on-brand);
  color: var(--ps-on-brand);
}

.ps--tone-brand { background: var(--ps-brand); }

.ps--tone-dark {
  --ps-brand: #0f172a;
  --ps-brand-light: rgba(255, 255, 255, .12);
  --ps-on-brand: #f1f5f9;
  background: #0f172a;
}

/* Headings inherit the tone: style-lean recolors h1–h6 in dark mode, which
   would otherwise fight a brand panel sitting on a light page.
   NOT :where() — that has zero specificity, so style-lean's own
   [data-theme="dark"] heading rules beat it and the panel ends up with light
   text on the light-blue that --ds-brand becomes in dark mode (1.91:1). */
.ps--tone-brand h1, .ps--tone-brand h2, .ps--tone-brand h3,
.ps--tone-brand h4, .ps--tone-brand h5, .ps--tone-brand h6,
.ps--tone-dark h1, .ps--tone-dark h2, .ps--tone-dark h3,
.ps--tone-dark h4, .ps--tone-dark h5, .ps--tone-dark h6 { color: var(--ps-on-brand); }

/* Adjacent same-tone sections read as one band, so only the seam gets a rule */
.ps--tone-raised + .ps--tone-surface,
.ps--tone-surface + .ps--tone-raised { border-top: 1px solid var(--ps-border); }

.ps__inner {
  width: 100%;
  max-width: var(--ps-w-default);
  margin-inline: auto;
  padding-inline: var(--ps-gutter);
}

.ps--container-narrow .ps__inner { max-width: var(--ps-w-narrow); }
.ps--container-wide   .ps__inner { max-width: var(--ps-w-wide); }
.ps--container-full   .ps__inner { max-width: none; padding-inline: 0; }

/* style-lean's .container does not scale fluidly — it steps at Bootstrap's
   breakpoints (540/720/960/1140 content). The default container mirrors those
   steps so a section's text edge lands on the same x as the rest of the site
   at every width, not just above 1200px. narrow/wide are deliberately outside
   this system: they are prose and full-width treatments the site has no
   equivalent for. */
.ps--container-default .ps__inner {
  /* No cap below 576px — the block just fills, exactly like .container. */
  max-width: none;
  /* .container's own gutter, so content+gutter always clears the breakpoint
     that activates it (960+30 < 992). The 28px gutter used elsewhere here
     would overflow a 1000px viewport. */
  padding-inline: 15px;
}
@media (min-width: 576px)  { .ps--container-default .ps__inner { max-width: 570px; } }
@media (min-width: 768px)  { .ps--container-default .ps__inner { max-width: 750px; } }
@media (min-width: 992px)  { .ps--container-default .ps__inner { max-width: 990px; } }
@media (min-width: 1200px) { .ps--container-default .ps__inner { max-width: var(--ps-w-default); } }

.ps--space-none { padding-block: 0; }
.ps--space-sm   { padding-block: clamp(1.5rem, 3vw, 1.875rem); }
.ps--space-md   { padding-block: clamp(2.5rem, 5vw, 3.5rem); }
.ps--space-lg   { padding-block: clamp(3rem, 7vw, 4.5rem); }

/* ── 3. Typography ────────────────────────────────────────────────────────── */
/* Sizes come from style-lean §03. Only the section-specific bits live here:
   the eyebrow, the lead measure, the mono figures, and margin resets. */

.ps-head {
  display: flex;
  flex-direction: column;
  gap: .75rem;
  margin-block-end: 2.25rem;
}

.ps-head:last-child { margin-block-end: 0; }

.ps-head--center {
  align-items: center;
  text-align: center;
  max-width: 46rem;
  margin-inline: auto;
}

.ps-eyebrow {
  margin: 0;
  font-size: var(--ds-eyebrow-size, .6875rem);
  font-weight: var(--ds-eyebrow-weight, 700);
  line-height: 1.2;
  letter-spacing: var(--ds-eyebrow-spacing, .1em);
  text-transform: uppercase;
  color: var(--ps-muted);
}

/* Heading tags keep the site scale; sections only drop the default margin and
   ask for balanced wrapping. */
.ps-title,
.ps-subtitle,
.ps-card__title { margin: 0; text-wrap: balance; }

/* Hero headings match the brand H1 exactly — style-lean §03 permits tuning
   hero H1 sizing, but the design board sized its heroes clamp(28px, 3.4vw,
   36px), which is that same range. No reason to exceed it. */
.ps-head--lg .ps-title {
  font-size: clamp(1.75rem, 4vw, 2.25rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -.02em;
}

.ps-lead {
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--ps-text-2);
  max-width: 58ch;
  text-wrap: pretty;
}

.ps-head--lg .ps-lead { font-size: 1.1875rem; }
.ps-head--center .ps-lead { margin-inline: auto; }
.ps-lead > :first-child { margin-block-start: 0; }
.ps-lead > :last-child { margin-block-end: 0; }

.ps-prose {
  line-height: 1.65;
  color: var(--ps-text-2);
}

.ps-prose > :first-child { margin-block-start: 0; }
.ps-prose > :last-child { margin-block-end: 0; }
.ps-prose p { margin-block: 0 .875rem; }

.ps-prose--long { font-size: 1.0625rem; max-width: 68ch; color: var(--ps-text); }
.ps-prose--long > * + * { margin-block-start: 1.25rem; }

.ps-footnote {
  margin: 1.5rem 0 0;
  font-size: .8125rem;
  line-height: 1.5;
  color: var(--ps-muted);
}

/* Mono numerals — the board sets every figure in JetBrains Mono */
.ps-figure-num {
  margin: 0;
  font-family: var(--ps-mono);
  font-weight: 700;
  font-size: 1.875rem;
  line-height: 1;
  letter-spacing: -.01em;
  color: var(--ps-link);
  font-variant-numeric: tabular-nums;
}

.ps-figure-num--xl { font-size: clamp(1.875rem, 3.5vw, 2.25rem); }

/* ── 4. Shared components: the deltas only ────────────────────────────────── */

/* Buttons are style-lean's .btn family. All that is needed here is the row. */
.ps-actions {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  margin-block-start: 1.5rem;
}

.ps-actions--center { justify-content: center; }
.ps-head + .ps-actions { margin-block-start: 0; }

/* Buttons on a filled panel.
   style-lean's dark-mode button rules assume the button sits on the *page*
   ground, and some of them are !important. A filled panel is the exception:
   in dark mode --ds-brand is a light blue, so the panel is lighter than the
   page and those rules would put a light-blue label on a light-blue panel.
   Restating the pair in the panel's own terms fixes both themes at once —
   .btn-white becomes "the panel's foreground color, filled". */
.ps .ps-actions--invert .btn.btn-white,
.ps .ps-tier--featured .btn.btn-white {
  background: var(--ps-on-brand);
  border-color: var(--ps-on-brand);
  color: var(--ps-brand) !important;
}

.ps .ps-actions--invert .btn.btn-white:hover,
.ps .ps-tier--featured .btn.btn-white:hover {
  background: color-mix(in srgb, var(--ps-on-brand) 88%, var(--ps-brand));
  border-color: color-mix(in srgb, var(--ps-on-brand) 88%, var(--ps-brand));
  color: var(--ps-brand) !important;
}

/* .btn-secondary is transparent by design; on a filled panel it takes the
   panel's foreground for both label and outline. */
.ps .ps-actions--invert .btn.btn-secondary,
.ps .ps-actions--invert .btn.btn--ghost {
  color: var(--ps-on-brand) !important;
  border-color: color-mix(in srgb, var(--ps-on-brand) 45%, transparent);
}

.ps .ps-actions--invert .btn.btn-secondary:hover,
.ps .ps-actions--invert .btn.btn--ghost:hover {
  background: color-mix(in srgb, var(--ps-on-brand) 14%, transparent);
  color: var(--ps-on-brand) !important;
  border-color: var(--ps-on-brand);
}

.ps-arrow { transition: transform .15s ease; }
.btn:hover .ps-arrow,
.ps-link:hover .ps-arrow { transform: translateX(2px); }

.ps-link {
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  min-height: 44px;              /* WCAG 2.2 AA target size */
  font-size: .875rem;
  font-weight: 600;
  color: var(--ps-link);
  text-decoration: none;
}

.ps-link:hover { color: var(--ps-link); text-decoration: underline; text-underline-offset: 3px; }

.ps-dot {
  width: .5rem; height: .5rem;
  border-radius: 50%;
  background: currentColor;
}

.ps-badge--dot-positive .ps-dot { background: var(--ps-positive-fill); }
.ps-badge--dot-warning  .ps-dot { background: var(--ps-warning-fill); }
.ps-badge--dot-brand    .ps-dot { background: var(--ps-brand); }

/* Chips are style-lean's [data-chip] component; this is only the list. */
.ps-chips {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ps-meta {
  display: flex;
  flex-wrap: wrap;
  gap: .625rem;
  margin: 1rem 0 0;
  padding: 0;
  list-style: none;
  font-size: .8125rem;
  color: var(--ps-muted);
}

.ps-meta li + li::before {
  content: "·";
  margin-inline-end: .625rem;
  color: var(--ps-border-strong);
}

.ps-hero--centered .ps-meta,
.ps-hero--compact .ps-meta { justify-content: center; }

/* Icons */
.ps-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--ps-link);
}

.ps-icon--tile {
  width: 2.875rem; height: 2.875rem;
  border-radius: var(--ps-radius-lg);
  background: var(--ps-brand-light);
}

.ps--tone-brand .ps-icon--tile,
.ps--tone-dark .ps-icon--tile { background: rgba(255, 255, 255, .12); }

.ps-icon--bare { font-size: 2.125rem; }

/* Ticked lists */
.ps-ticks {
  display: grid;
  gap: .625rem;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: .9375rem;
  line-height: 1.45;
  color: var(--ps-text-2);
}

.ps-ticks li {
  display: grid;
  grid-template-columns: 1.125rem 1fr;
  gap: .5625rem;
  align-items: start;
}

.ps-ticks li::before {
  content: "\2713";
  color: var(--ps-link);
  font-weight: 700;
  line-height: 1.45;
}

.ps-ticks li.is-excluded { color: var(--ps-muted); text-decoration: line-through; }
.ps-ticks li.is-excluded::before { content: "\2013"; color: var(--ps-muted); text-decoration: none; }

/* ── 5. Figures ───────────────────────────────────────────────────────────── */

.ps-figure {
  position: relative;
  overflow: hidden;
  border-radius: var(--ps-radius-lg);
  background: var(--ps-sunken);
}

.ps-figure img {
  display: block;
  width: 100%;
  height: 100%;
  margin: 0;
}

.ps-figure--fill { border-radius: 0; height: 100%; }

.ps-figure__placeholder {
  display: block;
  width: 100%; height: 100%;
  min-height: 12rem;
  background:
    repeating-linear-gradient(
      135deg,
      transparent 0 10px,
      color-mix(in srgb, var(--ps-border) 60%, transparent) 10px 11px
    );
}

/* ── 6. Hero ──────────────────────────────────────────────────────────────── */

.ps-hero__inner { display: grid; gap: clamp(2rem, 4vw, 3rem); }

.ps-hero__copy { display: flex; flex-direction: column; align-items: flex-start; gap: 1.125rem; }

.ps-hero--centered .ps-hero__copy,
.ps-hero--compact .ps-hero__copy { align-items: center; text-align: center; max-width: 45rem; margin-inline: auto; }

.ps-hero--centered .ps-head,
.ps-hero--compact .ps-head { margin-block-end: 0; }

.ps-hero--split .ps-hero__inner,
.ps-hero--split-reverse .ps-hero__inner { align-items: center; }

.ps-hero--split-reverse .ps-hero__copy { order: 2; }

.ps-hero--compact { --ps-w-default: 900px; }

/* Full-bleed: media under a scrim, copy on top */
.ps-hero--fullbleed {
  --ps-text: var(--ps-on-brand);
  --ps-text-2: var(--ps-on-brand-dim);
  --ps-muted: var(--ps-on-brand-dim);
  --ps-border: rgba(255, 255, 255, .22);
  --ps-border-strong: rgba(255, 255, 255, .4);
  --ps-link: var(--ps-on-brand);
  --ps-focus: #ffffff;
  background: var(--ps-brand);
  color: var(--ps-on-brand);
  overflow: hidden;
}

.ps-hero--fullbleed h1, .ps-hero--fullbleed h2, .ps-hero--fullbleed h3,
.ps-hero--fullbleed h4, .ps-hero--fullbleed h5, .ps-hero--fullbleed h6 { color: var(--ps-on-brand); }

.ps-hero__media { position: absolute; inset: 0; }
.ps-hero__media img { width: 100%; height: 100%; object-fit: cover; }

.ps-hero__scrim { position: absolute; inset: 0; }

.ps-hero--overlay-strong .ps-hero__scrim { background: color-mix(in srgb, var(--ps-brand) 88%, transparent); }
.ps-hero--overlay-medium .ps-hero__scrim {
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--ps-brand) 92%, transparent) 0%,
    color-mix(in srgb, var(--ps-brand) 72%, transparent) 52%,
    color-mix(in srgb, var(--ps-brand) 35%, transparent) 100%
  );
}
.ps-hero--overlay-soft .ps-hero__scrim { background: rgba(15, 23, 42, .55); }

.ps-hero--fullbleed .ps-hero__inner { position: relative; }
.ps-hero--fullbleed .ps-hero__copy { max-width: 38rem; }

@media (min-width: 62rem) {
  .ps-hero--split .ps-hero__inner,
  .ps-hero--split-reverse .ps-hero__inner { grid-template-columns: 1fr 1fr; }
  .ps-hero--split-reverse .ps-hero__aside { order: 1; }
}

/* ── 7. Stats ─────────────────────────────────────────────────────────────── */

.ps-stats__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 1.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ps-stats--strip .ps-stats__grid { text-align: center; max-width: 56rem; margin-inline: auto; }

.ps-stats--cards .ps-stats__item {
  padding: 1.5rem;
  border: 1px solid var(--ps-border);
  border-radius: var(--ps-radius-lg);
  background: var(--ps-surface);
  box-shadow: var(--ps-shadow);
}

.ps-stats__label {
  margin: .5rem 0 0;
  font-size: .8125rem;
  line-height: 1.45;
  color: var(--ps-text-2);
}

.ps-stats__note { display: block; margin-block-start: .25rem; color: var(--ps-muted); font-size: .75rem; }

.ps-stats__rows { margin: 0; }

.ps-stats__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: 1rem;
  border-block-end: 1px solid var(--ps-border);
}

.ps-stats__row:first-child { border-block-start: 1px solid var(--ps-border); }

.ps-stats__row-label { margin: 0; font-weight: 500; color: var(--ps-text); }
.ps-stats__row-value { display: flex; align-items: baseline; gap: .75rem; margin: 0; }

.ps-delta { font-family: var(--ps-mono); font-size: .8125rem; font-weight: 600; }
.ps-delta--positive { color: var(--ps-positive); }
.ps-delta--negative { color: var(--ps-negative); }
.ps-delta--neutral  { color: var(--ps-muted); }

/* ── 8. Feature rows ──────────────────────────────────────────────────────── */

.ps-feature__rows { display: grid; gap: clamp(2.5rem, 6vw, 4rem); }

.ps-feature__row { display: grid; gap: clamp(1.5rem, 4vw, 3rem); align-items: center; }

.ps-feature__copy { display: flex; flex-direction: column; align-items: flex-start; gap: .875rem; }

@media (min-width: 56rem) {
  .ps-feature__row { grid-template-columns: 1fr 1fr; }
  .ps-feature--ratio-copy  .ps-feature__row { grid-template-columns: 1.15fr .85fr; }
  .ps-feature--ratio-media .ps-feature__row { grid-template-columns: .85fr 1.15fr; }

  .ps-feature__row--media-left .ps-feature__copy  { order: 2; }
  .ps-feature__row--media-left .ps-feature__media { order: 1; }
}

/* ── 9. Cards ─────────────────────────────────────────────────────────────── */

.ps-cards__grid,
.ps-pricing__grid,
.ps-steps__list,
.ps-quote__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr));
  gap: 1.375rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 56rem) {
  .ps-cards__grid,
  .ps-pricing__grid,
  .ps-steps--cards .ps-steps__list,
  .ps-quote--grid .ps-quote__grid { grid-template-columns: repeat(var(--ps-cols), minmax(0, 1fr)); }
}

.ps-card { display: flex; flex-direction: column; gap: .75rem; }

.ps-cards--card .ps-card {
  padding: 1.625rem;
  border: 1px solid var(--ps-border);
  border-radius: var(--ps-radius-lg);
  background: var(--ps-surface);
  box-shadow: var(--ps-shadow);
}

.ps-cards--row .ps-cards__grid { grid-template-columns: 1fr; }

.ps-cards--row .ps-card {
  flex-direction: row;
  align-items: flex-start;
  gap: 1rem;
  padding: 1.125rem;
  border: 1px solid var(--ps-border);
  border-radius: var(--ps-radius-lg);
  box-shadow: var(--ps-shadow);
}

.ps-cards--row .ps-card__body { flex: 1; }
.ps-cards--plain .ps-card { gap: .625rem; }

.ps-card__link { margin-block-start: auto; }

/* ── 10. Steps ────────────────────────────────────────────────────────────── */

.ps-steps__item { display: flex; flex-direction: column; gap: .625rem; }

.ps-steps--cards .ps-steps__item {
  padding: 1.625rem;
  border: 1px solid var(--ps-border);
  border-radius: var(--ps-radius-lg);
  background: var(--ps-raised);
}

.ps-steps--list .ps-steps__list,
.ps-steps--timeline .ps-steps__list { grid-template-columns: 1fr; gap: 0; }

.ps-steps--list .ps-steps__item,
.ps-steps--timeline .ps-steps__item {
  flex-direction: row;
  gap: 1.25rem;
  padding-block: 1.5rem;
  border-block-end: 1px solid var(--ps-border);
}

.ps-steps--timeline .ps-steps__item { position: relative; padding-inline-start: .25rem; border-block-end: 0; }

.ps-steps--timeline .ps-steps__item:not(:last-child)::before {
  content: "";
  position: absolute;
  inset-block: 3rem 0;
  inset-inline-start: 1.0625rem;
  width: 1px;
  background: var(--ps-border);
}

.ps-steps__num { font-size: 1.375rem; flex: none; }

.ps-steps--timeline .ps-steps__num {
  display: grid;
  place-items: center;
  width: 2.125rem; height: 2.125rem;
  border-radius: 50%;
  background: var(--ps-brand-light);
  font-size: .8125rem;
}

.ps-steps__body { display: flex; flex-direction: column; gap: .5rem; }

/* ── 11. Bento ────────────────────────────────────────────────────────────── */

.ps-bento__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
  gap: 1.125rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ps-bento__tile {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 1rem;
  min-height: 11.5rem;
  padding: 1.5rem;
  border: 1px solid var(--ps-border);
  border-radius: 14px;
  overflow: hidden;
}

.ps-bento__tile--tone-surface { background: var(--ps-surface); box-shadow: var(--ps-shadow); }
.ps-bento__tile--tone-raised  { background: var(--ps-raised); }

/* Same pairing rule as the section tones above — see §2. */
.ps-bento__tile--tone-brand,
.ps-bento__tile--tone-dark {
  /* Re-declared, not inherited: --ps-on-brand-dim resolves on the element
     that declares it, so a tile re-pointing --ps-on-brand needs its own. */
  --ps-on-brand-dim: color-mix(in srgb, var(--ps-on-brand) 90%, var(--ps-brand));
  --ps-text: var(--ps-on-brand);
  --ps-text-2: var(--ps-on-brand-dim);
  --ps-muted: var(--ps-on-brand-dim);
  --ps-border: color-mix(in srgb, var(--ps-on-brand) 24%, transparent);
  --ps-link: var(--ps-on-brand);
  color: var(--ps-on-brand);
  border-color: transparent;
}

/* Cards that paint their own brand surface need the whole foreground pair,
   otherwise --ps-muted still resolves to the page's gray and lands at 2.07:1
   on the panel. Same remap as .ps--tone-brand, scoped to the card. */
.ps-tier--featured,
.ps-bento__tile--tone-brand,
.ps-bento__tile--tone-dark {
  --ps-text: var(--ps-on-brand);
  --ps-text-2: var(--ps-on-brand-dim);
  --ps-muted: var(--ps-on-brand-dim);
  --ps-border: color-mix(in srgb, var(--ps-on-brand) 24%, transparent);
  --ps-link: var(--ps-on-brand);
}

.ps-bento__tile--tone-brand { background: var(--ps-brand); }

.ps-bento__tile--tone-dark {
  --ps-brand: #0f172a;
  --ps-brand-light: rgba(255, 255, 255, .12);
  --ps-on-brand: #f1f5f9;
  background: #0f172a;
}

.ps-bento__tile--tone-brand h1, .ps-bento__tile--tone-brand h2, .ps-bento__tile--tone-brand h3,
.ps-bento__tile--tone-brand h4, .ps-bento__tile--tone-brand h5, .ps-bento__tile--tone-brand h6,
.ps-bento__tile--tone-dark h1, .ps-bento__tile--tone-dark h2, .ps-bento__tile--tone-dark h3,
.ps-bento__tile--tone-dark h4, .ps-bento__tile--tone-dark h5, .ps-bento__tile--tone-dark h6 { color: var(--ps-on-brand); }

.ps-bento__tile--image { padding: 0; }
.ps-bento__tile--stat  { justify-content: center; gap: .375rem; }

.ps-bento__body { display: flex; flex-direction: column; gap: .5rem; }

/* style-lean gives every blockquote a 45px margin and a left rule; inside a
   tile that reads as a stray divider. */
.ps-bento__quote {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 1.0625rem;
  font-weight: 500;
  line-height: 1.5;
}

.ps-bento__quote p { margin: 0 !important; font-size: inherit; font-weight: inherit; line-height: inherit; }
.ps-bento__cite { margin: .5rem 0 0; font-size: .8125rem; color: var(--ps-muted); }

@media (min-width: 56rem) {
  .ps-bento__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-rows: minmax(11.5rem, auto); }
  .ps-bento__tile--span-2-1 { grid-column: span 2; }
  .ps-bento__tile--span-1-2 { grid-row: span 2; }
  .ps-bento__tile--span-2-2 { grid-column: span 2; grid-row: span 2; }
}

/* ── 12. Pricing ──────────────────────────────────────────────────────────── */

.ps-pricing__grid { align-items: start; }

.ps-tier {
  display: flex;
  flex-direction: column;
  gap: 1.125rem;
  height: 100%;
  padding: 1.75rem;
  border: 1px solid var(--ps-border);
  border-radius: var(--ps-radius-lg);
  background: var(--ps-surface);
}

.ps-tier--featured {
  /* Re-declared, not inherited: --ps-on-brand-dim resolves on the element
     that declares it, so a tile re-pointing --ps-on-brand needs its own. */
  --ps-on-brand-dim: color-mix(in srgb, var(--ps-on-brand) 90%, var(--ps-brand));
  --ps-text: var(--ps-on-brand);
  --ps-text-2: var(--ps-on-brand-dim);
  --ps-muted: var(--ps-on-brand-dim);
  --ps-link: var(--ps-on-brand);
  background: var(--ps-brand);
  border-color: var(--ps-brand);
  color: var(--ps-on-brand);
  box-shadow: var(--ps-shadow-lg);
}

.ps-tier--featured .ps-figure-num,
.ps-tier--featured .ps-eyebrow,
.ps-tier--featured h1, .ps-tier--featured h2, .ps-tier--featured h3,
.ps-tier--featured h4, .ps-tier--featured h5, .ps-tier--featured h6 { color: var(--ps-on-brand); }

.ps-tier__badge {
  align-self: flex-start;
  margin: 0;
  padding: .25rem .625rem;
  border-radius: 999px;
  background: var(--ps-on-brand);
  color: var(--ps-brand);
  font-size: .6875rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.ps-tier:not(.ps-tier--featured) .ps-tier__badge { background: var(--ps-brand-light); color: var(--ps-brand); }

.ps-tier__price { display: flex; align-items: baseline; gap: .375rem; margin: 0; }
.ps-tier__price .ps-figure-num { font-size: 2.125rem; color: var(--ps-text); }
.ps-tier__price-note { font-size: .875rem; color: var(--ps-muted); }
.ps-tier__summary { font-size: .875rem; }
.ps-tier__features { font-size: .875rem; }
.ps-tier__cta { margin-block-start: auto; justify-content: center; }

/* ── 13. Comparison table ─────────────────────────────────────────────────── */

.ps-compare__scroll { overflow-x: auto; }

.ps-compare__table {
  width: 100%;
  border-collapse: collapse;
  font-size: .875rem;
  text-align: start;
}

.ps-compare__table th,
.ps-compare__table td {
  padding: .875rem 1rem;
  border-block-end: 1px solid var(--ps-border);
  text-align: start;
  vertical-align: top;
}

.ps-compare__table thead th {
  border-block-end: 2px solid var(--ps-border-strong);
  color: var(--ps-text);
  font-weight: 700;
}

.ps-compare__col-label { display: block; }
.ps-compare__col-note {
  display: block;
  margin-block-start: .25rem;
  font-family: var(--ps-mono);
  font-size: .75rem;
  font-weight: 400;
  line-height: 1.3;
  color: var(--ps-muted);
}

.ps-compare__table tbody th { font-weight: 500; color: var(--ps-text); }
.ps-compare__table td { color: var(--ps-text-2); }

.ps-compare__group th {
  padding-block: 1.25rem .5rem;
  border-block-end: 0;
  font-size: .6875rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ps-muted);
}

/* The tint lifts the ground, so the highlighted column takes the primary text
   color — secondary and muted both drop under 7:1 on #dce5ec. */
.ps-compare__table .is-highlighted { background: var(--ps-brand-light); color: var(--ps-text); }
.ps-compare__table .is-highlighted .ps-compare__col-note { color: var(--ps-text); }
/* Brand, not green: the tick must clear 3:1 as a non-text indicator on the
   highlighted column too, where a green tick lands at 2.9:1. */
.ps-tick  { color: var(--ps-link); font-weight: 700; }
.ps-cross { color: var(--ps-muted); }

/* ── 14. Checklist & scorecard ────────────────────────────────────────────── */

.ps-checklist__list {
  display: grid;
  gap: .875rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 48rem) {
  .ps-checklist--columns .ps-checklist__list { grid-template-columns: repeat(var(--ps-cols), minmax(0, 1fr)); }
}

.ps-checklist__item {
  display: grid;
  grid-template-columns: 1.25rem 1fr;
  gap: .625rem;
  align-items: start;
  font-size: .9375rem;
  line-height: 1.5;
  color: var(--ps-text-2);
}

.ps-checklist__item::before {
  content: "\2713";
  color: var(--ps-link);
  font-weight: 700;
}

.ps-checklist--marker-dot .ps-checklist__item::before { content: "\2022"; }
.ps-checklist--marker-number .ps-checklist__list { counter-reset: ps-step; }
.ps-checklist--marker-number .ps-checklist__item { counter-increment: ps-step; }
.ps-checklist--marker-number .ps-checklist__item::before {
  content: counter(ps-step);
  font-family: var(--ps-mono);
  font-size: .8125rem;
}

.ps-checklist__label { color: var(--ps-text); font-weight: 500; }
.ps-checklist__detail { grid-column: 2; margin-block-start: .25rem; font-size: .875rem; }

.ps-checklist--scorecard .ps-checklist__item {
  padding-block: .875rem;
  border-block-end: 1px solid var(--ps-border);
}

.ps-checklist--scorecard .is-pending::before { content: "\2013"; color: var(--ps-warning); }
.ps-checklist--scorecard .is-na::before { content: "\00B7"; color: var(--ps-muted); }
.ps-checklist--scorecard .is-na .ps-checklist__label { color: var(--ps-muted); }

.ps-score { display: flex; align-items: center; gap: 1rem; margin: 0 0 1.5rem; }

.ps-score__bar {
  flex: 1;
  height: .5rem;
  max-width: 20rem;
  border-radius: 999px;
  background: var(--ps-sunken);
  overflow: hidden;
}

.ps-score__bar > span { display: block; height: 100%; border-radius: inherit; background: var(--ps-link); }

/* ── 15. FAQ ──────────────────────────────────────────────────────────────── */

.ps-faq__inner { display: grid; gap: 2rem; }
.ps-faq__list { display: grid; gap: .75rem; }

@media (min-width: 56rem) {
  .ps-faq--split .ps-faq__inner { grid-template-columns: minmax(0, 20rem) minmax(0, 1fr); gap: 3rem; align-items: start; }
  .ps-faq--split .ps-faq__intro { position: sticky; top: 2rem; }
  .ps-faq--open .ps-faq__list { grid-template-columns: repeat(var(--ps-cols), minmax(0, 1fr)); gap: 2rem; }
}

.ps-faq__group {
  margin: 1.5rem 0 .25rem;
  font-size: .6875rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ps-muted);
}

.ps-faq__group:first-child { margin-block-start: 0; }

.ps-faq__details {
  border: 1px solid var(--ps-border);
  border-radius: var(--ps-radius-lg);
  background: var(--ps-surface);
}

.ps-faq__details .ps-faq__question {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 44px;
  padding: 1rem 1.25rem;
  margin: 0;
  cursor: pointer;
  list-style: none;
}

.ps-faq__details .ps-faq__question::-webkit-details-marker { display: none; }
.ps-faq__details .ps-faq__answer { padding: 0 1.25rem 1.25rem; }

/* style-lean's focus ring covers a, button and form controls — not summary. */
.ps-faq__question:focus-visible { outline: 3px solid var(--ps-focus); outline-offset: 3px; border-radius: var(--ds-radius-xs, 4px); }

.ps-faq__chevron {
  flex: none;
  width: .5rem; height: .5rem;
  border-inline-end: 2px solid currentColor;
  border-block-end: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform .15s ease;
}

.ps-faq__details[open] .ps-faq__chevron { transform: rotate(-135deg); }

.ps-faq--open .ps-faq__question { margin: 0 0 .5rem; }
.ps-faq--open .ps-faq__item + .ps-faq__item { margin-block-start: 1.5rem; }

/* ── 16. Quote ────────────────────────────────────────────────────────────── */

.ps-quote__item { margin: 0; display: flex; flex-direction: column; gap: 1rem; }

/* Overrides style-lean's global blockquote rule (45px margins, left border),
   which is tuned for quotes inside article prose, not for a full-width band. */
.ps-quote__text {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.5;
  color: var(--ps-text);
  text-wrap: pretty;
}

.ps-quote__text p {
  margin: 0 !important;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
}

.ps-quote__text::before { content: "\201C"; }
.ps-quote__text::after  { content: "\201D"; }

.ps-quote__cite { display: flex; flex-direction: column; gap: .125rem; font-size: .875rem; }
.ps-quote__author { font-weight: 600; color: var(--ps-text); }
.ps-quote__role { color: var(--ps-muted); }
.ps-quote__portrait { width: 3.5rem; height: 3.5rem; border-radius: 50%; object-fit: cover; }

.ps-quote--band .ps-quote__item { align-items: center; text-align: center; max-width: 52rem; margin-inline: auto; }
.ps-quote--band .ps-quote__text { font-size: clamp(1.25rem, 2.4vw, 1.5rem); }
.ps-quote--band .ps-quote__cite { align-items: center; }

.ps-quote--plain .ps-quote__item { border-block-start: 2px solid var(--ps-border-strong); padding-block-start: 1.5rem; }

.ps-quote--card .ps-quote__item {
  flex-direction: row;
  align-items: center;
  gap: 1.5rem;
  padding: 1.75rem;
  border: 1px solid var(--ps-border);
  border-radius: var(--ps-radius-lg);
  background: var(--ps-surface);
  box-shadow: var(--ps-shadow);
}

.ps-quote--grid .ps-quote__text { font-size: 1rem; font-weight: 500; }

/* ── 17. Logos ────────────────────────────────────────────────────────────── */

.ps-logos__inner { display: flex; flex-direction: column; align-items: center; gap: 1.125rem; text-align: center; }

.ps-logos__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 1.5rem 2.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ps-logos__item img {
  display: block;
  width: auto;
  max-width: 8rem;
  max-height: 2.25rem;
  object-fit: contain;
}

.ps-logos__wordmark { font-size: 1rem; font-weight: 600; color: var(--ps-muted); }

.ps-logos--muted .ps-logos__item { filter: grayscale(1); opacity: .75; transition: filter .15s ease, opacity .15s ease; }
.ps-logos--muted .ps-logos__item:hover,
.ps-logos--muted .ps-logos__item:focus-within { filter: none; opacity: 1; }

.ps-logos--grid .ps-logos__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 1px;
  background: var(--ps-border);
  border: 1px solid var(--ps-border);
  border-radius: var(--ps-radius-lg);
  overflow: hidden;
}

.ps-logos--grid .ps-logos__item {
  display: grid;
  place-items: center;
  min-height: 5.5rem;
  padding: 1rem;
  background: var(--ps-surface);
}

/* ── 18. CTA ──────────────────────────────────────────────────────────────── */

.ps-cta__panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  padding: clamp(2rem, 5vw, 3.25rem) clamp(1.5rem, 4vw, 2.5rem);
  border-radius: var(--ps-radius-xl);
  text-align: center;
}

/* The panel inherits the section tone; an unfilled section gets a bordered
   card so the CTA still reads as a distinct band. */
.ps--tone-surface.ps-cta .ps-cta__panel,
.ps--tone-none.ps-cta .ps-cta__panel { background: var(--ps-raised); border: 1px solid var(--ps-border); }

.ps-cta--inline .ps-cta__panel {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  text-align: start;
}

/* The panel's own gap already separates copy from actions, so the defaults
   that space a heading from the buttons below it are canceled here. */
.ps-cta__copy { min-width: 0; }
.ps-cta__panel .ps-head { margin-block-end: 0; }
.ps-cta__panel .ps-actions { margin-block-start: 0; }

.ps-cta__actions { display: flex; flex-direction: column; align-items: center; }
.ps-cta--inline .ps-cta__actions { align-items: flex-start; }

.ps-cta--bar .ps__inner { max-width: none; padding-inline: 0; }
.ps-cta--bar .ps-cta__panel { border-radius: 0; }

.ps-cta__note { margin: .75rem 0 0; font-size: .8125rem; color: var(--ps-muted); }

@media (max-width: 47.99rem) {
  .ps-cta--inline .ps-cta__panel { flex-direction: column; align-items: flex-start; }
}

/* ── 19. Signup ───────────────────────────────────────────────────────────── */

.ps-signup__inner {
  display: grid;
  gap: 2rem;
  padding-block: clamp(1.75rem, 4vw, 2.5rem);
  padding-inline: clamp(1.5rem, 4vw, 2.5rem);
  border: 1px solid var(--ps-border);
  border-radius: var(--ps-radius-xl);
  background: var(--ps-raised);
}

.ps-signup__copy { display: flex; flex-direction: column; gap: 1rem; }

.ps-signup__form form {
  display: flex;
  flex-direction: column;
  gap: .75rem;
  padding: 1.5rem;
  border: 1px solid var(--ps-border);
  border-radius: var(--ps-radius-lg);
  background: var(--ps-surface);
  box-shadow: var(--ps-shadow);
}

.ps-field { display: flex; flex-direction: column; gap: .375rem; }

/* style-lean §06 styles the control itself; these are the deltas a stacked
   field needs — its 20px bottom margin, the target floor and the radius. */
.ps-field__label { margin: 0; font-size: .8125rem; font-weight: 600; color: var(--ps-text); }

.ps-field__input {
  margin: 0;
  min-height: 44px;
  border-radius: var(--ps-radius);
  border-color: var(--ps-border-strong);
  background: var(--ps-surface);
  color: var(--ps-text);
}

.ps-field__help { margin: 0; font-size: .75rem; line-height: 1.45; color: var(--ps-muted); }

.ps-signup--centered .ps-signup__inner { justify-items: center; text-align: center; max-width: 40rem; margin-inline: auto; }
.ps-signup--centered .ps-signup__form { width: 100%; }

.ps-signup--inline .ps-signup__form form { flex-direction: row; align-items: flex-end; flex-wrap: wrap; }
.ps-signup--inline .ps-field { flex: 1 1 14rem; }

@media (min-width: 56rem) {
  .ps-signup--split .ps-signup__inner { grid-template-columns: 1fr .9fr; align-items: center; gap: 2.5rem; }
}

/* ── 20. Media band ───────────────────────────────────────────────────────── */

.ps-media__figure { margin: 0; }
.ps-media__frame { display: grid; gap: 1rem; }
.ps-media--duo .ps-media__frame { grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr)); }
.ps-media--bleed .ps__inner { max-width: none; padding-inline: 0; }
.ps-media--bleed .ps-figure { border-radius: 0; }

.ps-media__caption { margin-block-start: .875rem; color: var(--ps-muted); }

.ps-media__caption--mono {
  font-family: var(--ps-mono);
  font-size: .75rem;
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: .04em;
  text-transform: uppercase;
}

.ps-media__caption--prose { font-size: .875rem; line-height: 1.6; }

/* ── 21. Prose column & rail ──────────────────────────────────────────────── */

.ps-prose-section__inner { display: grid; gap: 2.5rem; }

.ps-rail__inner { display: flex; flex-direction: column; gap: 1rem; }
.ps-rail__nav ul { margin: 0; padding: 0; list-style: none; display: grid; gap: .125rem; }

.ps-rail__nav a,
.ps-rail__nav span {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding-inline-start: .875rem;
  border-inline-start: 2px solid var(--ps-border);
  font-size: .875rem;
  line-height: 1.4;
  color: var(--ps-text-2);
  text-decoration: none;
}

.ps-rail__nav a:hover { border-inline-start-color: var(--ps-brand); color: var(--ps-text); }

.ps-rail__meta {
  margin: 0;
  padding: 1.25rem;
  border: 1px solid var(--ps-border);
  border-radius: var(--ps-radius-lg);
  background: var(--ps-raised);
  font-size: .875rem;
}

.ps-rail__meta dt { font-weight: 600; color: var(--ps-text); }
.ps-rail__meta dd { margin: 0 0 .875rem; color: var(--ps-text-2); }
.ps-rail__meta dd:last-child { margin-block-end: 0; }

@media (min-width: 62rem) {
  .ps-prose-section--rail-left.has-rail .ps-prose-section__inner  { grid-template-columns: minmax(0, 15rem) minmax(0, 1fr); }
  .ps-prose-section--rail-right.has-rail .ps-prose-section__inner { grid-template-columns: minmax(0, 1fr) minmax(0, 18rem); }
  .ps-prose-section--rail-left .ps-prose-section__main { order: 2; }
  .ps-prose-section--rail-left .ps-rail { order: 1; }
  .ps-rail__inner { position: sticky; top: 2rem; }
}

/* The prose column hosts the site's extended blocks (metrics, timeline, charts,
   …). They bring their own styling; all that is needed here is the rhythm. */
.ps-prose--long > .blocks > * + * { margin-block-start: 1.5rem; }

/* ── 22. Focus, motion, print ─────────────────────────────────────────────── */

/* style-lean §02 already covers a, button, input, select and textarea.
   Only the elements it does not reach are handled here. */
.ps :where(summary, [tabindex]):focus-visible {
  outline: 3px solid var(--ps-focus);
  outline-offset: 3px;
  border-radius: var(--ds-radius-xs, 4px);
}

@media (prefers-reduced-motion: reduce) {
  .ps *,
  .ps *::before,
  .ps *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
  }
}

@media print {
  .ps { background: none !important; color: #000 !important; padding-block: 1rem; }
  .ps-hero__media,
  .ps-figure__placeholder { display: none; }
  .ps-faq__details { border: 0; }
  .ps-faq__details > .ps-faq__answer { display: block !important; }
}

/* ─────────────────────────────────────────────────────────────
   Section — Form
   Editor-defined fields. Sizing follows the site's 44px minimum
   tap target; focus uses the same 3px brand outline as the rest
   of the site rather than a bespoke ring.
   ───────────────────────────────────────────────────────────── */

.ps-form__inner { display: grid; gap: clamp(1.5rem, 4vw, 3rem); }
.ps-form--split .ps-form__inner { grid-template-columns: 1fr; }

@media (min-width: 56rem) {
  .ps-form--split .ps-form__inner { grid-template-columns: 1fr 1fr; align-items: start; }
}

.ps-form--centered .ps-form__inner,
.ps-form--plain .ps-form__inner { max-width: 42rem; margin-inline: auto; }

.ps-form--split .ps-form__panel,
.ps-form--centered .ps-form__panel {
  background: var(--ds-surface, #fff);
  border: 1px solid var(--ds-border, #e5e7eb);
  border-radius: var(--ds-radius-lg, 12px);
  padding: clamp(1.25rem, 3vw, 2rem);
}

.ps-form__grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem; }
.ps-form__field--full { grid-column: 1 / -1; }
.ps-form__field--half { grid-column: 1 / -1; }

@media (min-width: 34rem) {
  .ps-form__field--half { grid-column: span 1; }
}

.ps-form__field { grid-column: 1 / -1; display: flex; flex-direction: column; gap: .375rem; }

.ps-form__label {
  font-size: .9375rem;
  font-weight: 600;
  color: var(--ds-text-primary, #232323);
}

.ps-form__req { color: var(--ds-error, #dc2626); }

/* Visible only to screen readers — carries "(required)" so the
   asterisk isn't the sole indicator. */
.ps-form__sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.ps-form__help { font-size: .875rem; color: var(--ds-text-secondary, #475569); margin: 0; }

.ps-form__error {
  font-size: .875rem;
  font-weight: 500;
  color: var(--ds-error-text, #991b1b);
  margin: 0;
}

/* Controls do not inherit typography by default; without this checkboxes and
   radios fall back to the UA font (Arial) rather than Inter. */
.ps-form__form input,
.ps-form__form select,
.ps-form__form textarea,
.ps-form__form button,
.ps-onboarding__check { font-family: inherit; }

.ps-form__form input[type="text"],
.ps-form__form input[type="email"],
.ps-form__form input[type="tel"],
.ps-form__form input[type="url"],
.ps-form__form input[type="number"],
.ps-form__form input[type="date"],
.ps-form__form textarea,
.ps-form__form select {
  width: 100%;
  min-height: 2.75rem;               /* 44px tap target */
  padding: .625rem .75rem;
  font: inherit;
  font-size: 1rem;                   /* 16px — stops iOS zoom on focus */
  color: var(--ds-text-primary, #232323);
  background: var(--ds-surface, #fff);
  border: 1px solid var(--ds-border-strong, #d1d5db);
  border-radius: var(--ds-radius, 8px);
}

.ps-form__form textarea { min-height: 7rem; resize: vertical; }

.ps-form__field--invalid input,
.ps-form__field--invalid textarea,
.ps-form__field--invalid select { border-color: var(--ds-error, #dc2626); }

.ps-form__fieldset { border: 0; padding: 0; margin: 0; display: flex; flex-direction: column; gap: .375rem; }
.ps-form__choices { display: flex; flex-direction: column; gap: .5rem; margin-top: .25rem; }

.ps-form__choice { display: flex; align-items: flex-start; gap: .625rem; min-height: 2.75rem; }
/* 1.5rem = 24px: WCAG 2.5.8 Target Size (Minimum), AA. Both the UA default
   and the 1.25rem this used to carry sit under that floor. */
.ps-form__choice input { width: 1.5rem; height: 1.5rem; margin-top: .0625rem; flex: none; }
.ps-form__choice label { font-size: .9375rem; line-height: 1.5; }

.ps-form__errors {
  border: 2px solid var(--ds-error, #dc2626);
  background: var(--ds-error-bg, #fef2f2);
  border-radius: var(--ds-radius, 8px);
  padding: 1rem;
  margin-bottom: 1.25rem;
}

.ps-form__errors-title { font-weight: 700; margin: 0 0 .5rem; color: var(--ds-error-text, #991b1b); }
.ps-form__errors ul { margin: 0; padding-left: 1.25rem; }
.ps-form__errors a { color: var(--ds-error-text, #991b1b); }

.ps-form__success {
  border: 2px solid var(--ds-success, #059669);
  background: var(--ds-success-bg, #ecfdf5);
  color: var(--ds-success-text, #065f46);
  border-radius: var(--ds-radius, 8px);
  padding: 1.25rem;
}

.ps-form__success p { margin: 0; }
.ps-form__actions { margin-top: 1.25rem; }
.ps-form__note { font-size: .8125rem; color: var(--ds-text-muted, #525252); margin: .75rem 0 0; }

/* Honeypot — hidden from sighted users and from assistive tech.
   display:none is deliberate: the field must not be reachable at all. */
.ps-form__hp { display: none; }

/* ─────────────────────────────────────────────────────────────
   Section — Onboarding checklist
   Progress column beside hairline rows (ui.beste.co onboarding33,
   board 15a). Bar and figure move together as rows are ticked.
   ───────────────────────────────────────────────────────────── */

.ps-onboarding__inner { display: grid; gap: clamp(1.5rem, 4vw, 3rem); }

@media (min-width: 56rem) {
  .ps-onboarding__inner { grid-template-columns: minmax(0, 20rem) 1fr; align-items: start; }
  .ps-onboarding__aside { position: sticky; top: 2rem; }
}

.ps-onboarding__figure { display: flex; align-items: baseline; gap: .5rem; margin: 1rem 0 .5rem; }

.ps-onboarding__figure .ps-figure-num {
  font-size: clamp(2.75rem, 8vw, 4rem);
  font-weight: 300;
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--ds-brand, #294557);
}

.ps-onboarding__figure-label { font-size: .9375rem; color: var(--ds-text-secondary, #475569); }

.ps-onboarding__bar {
  display: block;
  height: .375rem;
  border-radius: 999px;
  background: var(--ds-border, #e5e7eb);
  overflow: hidden;
}

.ps-onboarding__bar-fill {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--ds-brand, #294557);
  transition: width .3s ease;
}

@media (prefers-reduced-motion: reduce) {
  .ps-onboarding__bar-fill { transition: none; }
}

.ps-onboarding__note { font-size: .8125rem; color: var(--ds-text-muted, #525252); margin: .625rem 0 0; }

.ps-onboarding__rows { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--ds-border, #e5e7eb); }

.ps-onboarding__row {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: .25rem .875rem;
  align-items: start;
  padding: 1rem 0;
  border-bottom: 1px solid var(--ds-border, #e5e7eb);
}

@media (min-width: 40rem) {
  .ps-onboarding__row { grid-template-columns: auto 1fr auto; align-items: center; }
}

.ps-onboarding__check {
  width: 1.5rem;
  height: 1.5rem;
  margin: .125rem 0 0;
  flex: none;
  accent-color: var(--ds-brand, #294557);
}

.ps-onboarding__body { min-width: 0; }

.ps-onboarding__label {
  display: inline-block;
  font-weight: 600;
  color: var(--ds-text-primary, #232323);
  /* 44px target without inflating the row: padding sits inside the grid cell */
  padding-block: .625rem;
  margin-block: -.625rem;
  cursor: pointer;
}

/* Strike-through is presentational only — the checkbox carries the real state */
.ps-onboarding__row.is-done .ps-onboarding__label {
  text-decoration: line-through;
  color: var(--ds-text-muted, #525252);
}

.ps-onboarding__text { font-size: .9375rem; line-height: 1.55; color: var(--ds-text-secondary, #475569); margin: .125rem 0 0; }

.ps-onboarding__link {
  grid-column: 2;
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  min-height: 2.75rem;
  font-size: .9375rem;
  font-weight: 600;
  white-space: nowrap;
  color: var(--ds-link, #294557);
}

@media (min-width: 40rem) {
  .ps-onboarding__link { grid-column: 3; }
}

/* Hero — media-on-top band (hero90) and the editorial band under (hero143) */
/* hero90: the band IS the section's top edge, so the section's own top padding
   would render as a gap between the page chrome and the photo. Drop it, and
   put the spacing where it belongs — under the image, before the copy. The
   author's chosen spacing still governs the bottom of the section. */
.ps-hero--media-top { padding-block-start: 0; }

.ps-hero--media-top .ps-hero__band {
  margin-block-end: clamp(1.75rem, 4vw, 2.75rem);
}

.ps-hero__band { width: 100%; overflow: hidden; }
.ps-hero__band img { display: block; width: 100%; height: clamp(18rem, 45vh, 32rem); object-fit: cover; }
.ps-hero__band--under img { height: clamp(18rem, 40vw, 28rem); }

/* hero143: mirror of the media-top case. Here the band is the section's BOTTOM
   edge, so the section's bottom padding would show as a gap under the photo,
   and the copy would otherwise sit flush on top of it. */
.ps-hero--editorial { padding-block-end: 0; }

.ps-hero--editorial .ps-hero__band--under {
  margin-block-start: clamp(1.75rem, 4vw, 2.75rem);
}

/* hero143: display heading left, copy + CTA right, aligned on their baselines */
.ps-hero--editorial .ps-hero__inner { display: grid; gap: clamp(1.5rem, 4vw, 3rem); }

@media (min-width: 48rem) {
  .ps-hero--editorial .ps-hero__inner { grid-template-columns: 1fr 1fr; align-items: end; }
}

.ps-hero--editorial .ps-title { font-weight: 700; letter-spacing: -.02em; }

/* hero120: image inside the measure with a monospace caption */
.ps-hero__figure { margin-top: clamp(1.5rem, 4vw, 2.5rem); }

.ps-figure__caption {
  margin: .625rem 0 0;
  font-family: var(--ds-font-mono, 'JetBrains Mono', monospace);
  font-size: .8125rem;
  color: var(--ds-text-muted, #525252);
}

.ps-title__accent { font-weight: inherit; color: var(--ds-text-muted, #525252); }

/* hero84: trust row with ticks rather than dot separators */
.ps-meta--checks { gap: .5rem 1.25rem; }
.ps-meta--checks li::before { content: none; }
.ps-meta__tick { color: var(--ds-success-text, #065f46); margin-right: .375rem; }

/* stats59: tall image beside the stat grid */
.ps-stats__split { display: grid; gap: clamp(1.5rem, 4vw, 3rem); }

@media (min-width: 52rem) {
  .ps-stats__split { grid-template-columns: minmax(0, 22rem) 1fr; align-items: start; }
}

.ps-stats__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: clamp(1.25rem, 3vw, 2rem); margin: 0; }
.ps-stats__cell { display: flex; flex-direction: column; gap: .25rem; }
.ps-stats__cell .ps-stats__value { margin: 0; }
.ps-stats__cell .ps-stats__label { font-size: .9375rem; color: var(--ds-text-secondary, #475569); }

/* ─────────────────────────────────────────────────────────────
   Section — About / figure strip (about39)
   Display line and paragraph share a bottom baseline; the image
   strip shares a bottom edge with a taller centre frame.
   ───────────────────────────────────────────────────────────── */

.ps-about__head { display: grid; gap: clamp(1rem, 3vw, 2rem); }

@media (min-width: 48rem) {
  /* items-end is the whole point: the paragraph meets the bottom of the
     display line rather than starting level with its top. */
  .ps-about__head { grid-template-columns: 1fr 1fr; align-items: end; }
}

.ps-about__display {
  /* about39 sets this as light 80px display type. style-lean §03 is the
     standard here, and it allows tuning a *hero H1* only — so the display
     treatment is scoped to h1 below and every other level keeps the brand
     scale. Nothing here overrides size or weight. */
  margin: .25rem 0 0;
  text-wrap: balance;
}

/* Hero-level display sizing, matching the brand H1 range exactly */
h1.ps-about__display {
  font-size: clamp(1.75rem, 4vw, 2.25rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -.02em;
}

.ps-about__display .ps-title__accent { color: var(--ds-brand, #294557); font-weight: inherit; }

.ps-about__text { color: var(--ds-text-secondary, #475569); }
.ps-about__text > :last-child { margin-bottom: 0; }

.ps-about__strip {
  list-style: none;
  margin: clamp(1.75rem, 5vw, 3rem) 0 0;
  padding: 0;
  display: grid;
  gap: clamp(.75rem, 2vw, 1.25rem);
  grid-template-columns: 1fr;
}

@media (min-width: 40rem) {
  .ps-about__strip { grid-template-columns: repeat(var(--ps-frames, 3), 1fr); align-items: end; }
  .ps-about__strip[data-count="1"] { --ps-frames: 1; }
  .ps-about__strip[data-count="2"] { --ps-frames: 2; }
  .ps-about__strip[data-count="3"] { --ps-frames: 3; }
}

.ps-about__frame { margin: 0; overflow: hidden; border-radius: var(--ds-radius-lg, 12px); }

.ps-about__frame img {
  display: block;
  width: 100%;
  height: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  transition: transform .5s ease;
}

/* The centre frame runs taller, which is what staggers the strip */
.ps-about__frame.is-tall img { aspect-ratio: 3 / 5; }

.ps-about__frame:hover img { transform: scale(1.05); }

@media (prefers-reduced-motion: reduce) {
  .ps-about__frame img { transition: none; }
  .ps-about__frame:hover img { transform: none; }
}

.ps-about__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: clamp(1.25rem, 3vw, 2rem);
}

.ps-about__caption { margin: 0; font-size: .9375rem; color: var(--ds-text-muted, #525252); max-width: 46ch; }

/* ── Foreground on filled panels ──────────────────────────────────────────
   style-lean recolors h1–h6 under [data-theme="dark"] at specificity (0,1,1).
   A single class + element ties that and loses on source order, which left
   near-white headings on the light blue --ds-brand becomes in dark mode —
   1.91:1. Doubling the class takes these to (0,2,1) so they win outright.
   Every filled surface is listed, not just section tones: cards paint brand
   themselves and need the same pair. */
.ps.ps--tone-brand h1, .ps.ps--tone-brand h2, .ps.ps--tone-brand h3,
.ps.ps--tone-brand h4, .ps.ps--tone-brand h5, .ps.ps--tone-brand h6,
.ps.ps--tone-dark h1, .ps.ps--tone-dark h2, .ps.ps--tone-dark h3,
.ps.ps--tone-dark h4, .ps.ps--tone-dark h5, .ps.ps--tone-dark h6,
.ps .ps-cta__panel h1, .ps .ps-cta__panel h2, .ps .ps-cta__panel h3,
.ps .ps-tier--featured h1, .ps .ps-tier--featured h2, .ps .ps-tier--featured h3,
.ps .ps-tier--featured h4, .ps .ps-tier--featured h5, .ps .ps-tier--featured h6,
.ps .ps-bento__tile--tone-brand h1, .ps .ps-bento__tile--tone-brand h2,
.ps .ps-bento__tile--tone-brand h3, .ps .ps-bento__tile--tone-brand h4,
.ps .ps-bento__tile--tone-dark h1, .ps .ps-bento__tile--tone-dark h2,
.ps .ps-bento__tile--tone-dark h3, .ps .ps-bento__tile--tone-dark h4,
.ps .ps-hero--fullbleed h1, .ps .ps-hero--fullbleed h2, .ps .ps-hero--fullbleed h3 {
  color: var(--ps-on-brand);
}

/* Non-heading text on those same surfaces: eyebrows, notes and prose all
   resolve through the tone tokens, so remap the pair on the panel itself. */
.ps .ps-cta__panel,
.ps .ps-tier--featured,
.ps .ps-bento__tile--tone-brand,
.ps .ps-bento__tile--tone-dark {
  --ps-text: var(--ps-on-brand);
  --ps-text-2: var(--ps-on-brand-dim);
  --ps-muted: var(--ps-on-brand-dim);
  --ps-link: var(--ps-on-brand);
  color: var(--ps-on-brand);
}

.ps .ps-cta__panel .ps-eyebrow,
.ps .ps-tier--featured .ps-eyebrow,
.ps .ps-bento__tile--tone-brand .ps-eyebrow,
.ps.ps--tone-brand .ps-eyebrow,
.ps.ps--tone-dark .ps-eyebrow { color: var(--ps-on-brand-dim); }

/* The tier name is a real subheading, so it takes the brand H3 (18px/600)
   rather than the 11px eyebrow treatment it used to borrow. style-lean §03:
   H2–H6 stay consistent everywhere. */
.ps-tier__name {
  margin: 0 0 .25rem;
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: -.01em;
  text-transform: none;
  color: inherit;
}

/* section-signup is retired from the picker but still renders for any content
   that already uses it — its controls need Inter too. */
.ps-signup__form input,
.ps-signup__form button,
.ps-field__input { font-family: inherit; }

/* style-lean's .badge has no brand-panel context, so invert it there. Additive
   only — the pill itself stays style-lean's component. */
.ps--tone-brand .badge--primary,
.ps--tone-dark .badge--primary,
.ps-hero--fullbleed .badge--primary {
  background: rgba(255, 255, 255, .14);
  border-color: rgba(255, 255, 255, .28);
  color: var(--ps-on-brand);
}

.ps-badge-row { gap: .5rem; align-self: flex-start; margin: 0; }

/* ── Classes the markup emitted with no rules behind them ────────────────────
   Found by diffing the classes the snippets output against the ones this file
   styles. Each of these was rendering as an unstyled default. */

/* about39: the paragraph sitting on the display line's baseline */
.ps-about__lead {
  margin: 0;
  color: var(--ps-text-secondary);
  text-wrap: pretty;
}

/* Comparison table's empty top-left header cell */
.ps-compare__corner {
  background: transparent;
  border: 0;
}

/* Consent rows put the box beside the label rather than above it */
.ps-form__choice--consent {
  display: flex;
  align-items: flex-start;
  gap: .625rem;
}

.ps-form__choice--consent input { margin-block-start: .0625rem; flex: none; }

/* Split-variant copy column */
.ps-form__copy {
  display: flex;
  flex-direction: column;
  gap: .75rem;
}

/* The anti-spam answer is a 1–2 digit sum, so it does not need a full-width
   input. Previously this borrowed .ps-form__field--narrow, a wrapper-grid
   modifier that never had rules and does not belong on an <input>. */
.ps-form__answer { max-width: 7rem; }

/* stats59: the tall image beside the figure grid */
.ps-stats__media {
  border-radius: var(--ds-radius-lg, 12px);
  overflow: hidden;
}
