.pd-container {
  width: min(
    100% - calc(var(--pd-container-inline-padding) * 2),
    var(--pd-container-max-width)
  );
  margin-inline: auto;
}

.pd-container--full {
  width: 100%;
  max-width: none;
}

.pd-section {
  padding-block: var(--pd-section-padding-block);
}

.pd-heading {
  margin: 0 0 var(--pd-space-4);
  font-family: var(--pd-font-heading);
  line-height: 1.2;
}

.pd-copy {
  margin: 0;
  color: var(--pd-color-muted);
}

/* PASS 4BN: shared CTA / button base. Every section CTA composes
 * .pd-button as the visual layer and keeps its package-specific
 * `__cta` class only for layout placement (margin, grid, alignment).
 * Visual styling - padding, radius, background, color, hover, focus,
 * transitions - lives here exclusively. Tone-aware contrast rules
 * are below; per-package tone overrides are removed across the
 * sections in this pass. Floating CTA stays exempt as a fixed
 * positioned pill component. */

.pd-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--pd-space-2);
  min-height: 2.75rem;
  padding: 0.625rem 1.125rem;
  border: 1px solid transparent;
  border-radius: var(--pd-radius-md);
  background: var(--pd-color-primary);
  color: var(--pd-color-on-dark);
  font-family: var(--pd-font-body);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition:
    background-color 160ms ease,
    color 160ms ease,
    border-color 160ms ease,
    filter 160ms ease,
    transform 160ms ease;
}

.pd-button:hover {
  filter: brightness(0.92);
  transform: translateY(-1px);
}

.pd-button:focus-visible {
  outline: 3px solid var(--pd-color-accent);
  outline-offset: 2px;
}

.pd-button[disabled],
.pd-button[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.55;
  pointer-events: none;
}

.pd-button--primary {
  background: var(--pd-color-primary);
  color: var(--pd-color-on-dark);
}

.pd-button--secondary {
  background: var(--pd-color-secondary);
  color: var(--pd-color-on-secondary);
  border-color: var(--pd-color-secondary);
}

.pd-button--ghost {
  background: transparent;
  border-color: rgb(13 42 51 / 28%);
  color: var(--pd-color-secondary);
}

.pd-button--ghost:hover {
  background: var(--pd-color-surface-alt);
  filter: none;
}

.pd-button--large {
  min-height: 3.25rem;
  padding: 0.875rem 1.5rem;
  font-size: 1.0625rem;
}

/* Tone-aware contrast: when a CTA sits on a primary or secondary
 * (dark) section background, invert to a surface fill so the button
 * stays readable. .pd-button--ghost on dark stays transparent with a
 * white border. Sections compose `.pd-button` then choose --primary
 * or --secondary; the tone wrapper does the rest. */
[data-background-tone="primary"] .pd-button,
[data-background-tone="secondary"] .pd-button,
[data-background-tone="primary"] .pd-button--primary,
[data-background-tone="secondary"] .pd-button--primary {
  background: var(--pd-color-surface);
  color: var(--pd-color-primary);
  border-color: var(--pd-color-surface);
}

[data-background-tone="primary"] .pd-button--secondary,
[data-background-tone="secondary"] .pd-button--secondary,
[data-background-tone="primary"] .pd-button--ghost,
[data-background-tone="secondary"] .pd-button--ghost {
  background: transparent;
  color: var(--pd-color-on-dark);
  border-color: rgba(255, 255, 255, 0.6);
}

[data-background-tone="primary"] .pd-button--ghost:hover,
[data-background-tone="secondary"] .pd-button--ghost:hover {
  background: rgba(255, 255, 255, 0.1);
}

@media (prefers-reduced-motion: reduce) {
  .pd-button {
    transition: none;
  }
  .pd-button:hover {
    transform: none;
  }
}

/* Shared background-tone primitive.
 *
 * Modules adopt this by rendering data-background-tone="<surface
 * |surface-alt|primary|secondary|transparent>" on their section root
 * and by NOT setting their own background/color on the root rule.
 * The shared selector here owns the bg/root color flip so per-module
 * scoped CSS only adds module-specific contrast tweaks (e.g. muted
 * text on dark tones) instead of repeating the five tone branches.
 *
 * Default tone is 'surface'. Modules SHOULD render the attribute
 * unconditionally (with a 'surface' default) so the cascade is
 * deterministic. */

[data-background-tone="surface"] {
  background: var(--pd-color-surface);
  color: var(--pd-color-text);
}

[data-background-tone="surface-alt"] {
  background: var(--pd-color-surface-alt);
  color: var(--pd-color-text);
}

[data-background-tone="primary"] {
  background: var(--pd-color-primary);
  color: var(--pd-color-on-dark);
}

[data-background-tone="secondary"] {
  background: var(--pd-color-secondary);
  color: var(--pd-color-on-secondary);
}

[data-background-tone="transparent"] {
  background: transparent;
}

/* Shared optional background-image primitive.
 *
 * Modules opt in by rendering data-background-image="true" plus an
 * inline style block setting --pd-section-bg-image (the url() value)
 * and --pd-section-bg-overlay-opacity. The phasma_v3_section_background_attrs()
 * helper in theme/inc/render.php produces the exact attribute string;
 * adopting modules splice it into their section open tag.
 *
 * Default tokens for both CSS variables are emitted into
 * tokens.generated.css (--pd-section-bg-image: none;
 * --pd-section-bg-overlay-opacity: 0;) so static CSS layers always
 * resolve every var() reference and the export token validator stays
 * green even when no module sets a background image.
 *
 * The overlay sits in the section's own stacking context (created via
 * isolation: isolate) at z-index: -1, between the section background
 * image and the section's child content - so children naturally sit
 * above the overlay without per-module z-index plumbing.
 *
 * Parallax (background-attachment: fixed) is disabled under 48rem and
 * for prefers-reduced-motion users; that shipped iOS smoothness
 * fallback is what we want, not a JavaScript parallax. */

[data-background-image="true"] {
  position: relative;
  isolation: isolate;
  background-image: var(--pd-section-bg-image);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

[data-background-image="true"]::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(0, 0, 0, var(--pd-section-bg-overlay-opacity));
  pointer-events: none;
}

[data-background-image="true"][data-background-image-mode="parallax"] {
  background-attachment: fixed;
}

@media (max-width: 47.999rem), (prefers-reduced-motion: reduce) {
  [data-background-image="true"][data-background-image-mode="parallax"] {
    background-attachment: scroll;
  }
}

/* Shared inversion helpers for descendants of a dark-tone section.
 * Module-scoped rules (e.g. .pd-section--<type>[data-pd-module] .pd-X)
 * still win specificity, so modules MUST add their own per-tone
 * overrides for any text-bearing class they explicitly color. These
 * helpers cover the unstyled defaults: shared utilities (.pd-eyebrow)
 * and bare hyperlinks. */

[data-background-tone="primary"] .pd-eyebrow,
[data-background-tone="secondary"] .pd-eyebrow {
  color: var(--pd-color-surface);
  opacity: 0.92;
}

[data-background-tone="primary"] a:not(.pd-button):not(.pd-button--ghost):not(.pd-button--secondary),
[data-background-tone="secondary"] a:not(.pd-button):not(.pd-button--ghost):not(.pd-button--secondary) {
  color: var(--pd-color-surface);
}

[data-background-tone="primary"] .pd-card,
[data-background-tone="secondary"] .pd-card {
  color: var(--pd-color-text);
}

/* Shared visual primitives - usable by any module's outer markup.
 * Module CSS may add scoped overrides under
 * .pd-section--<type>[data-pd-module] but must not redefine these
 * primitives globally. Tokens listed in tokens.css are the only
 * source of truth for color/space/radius/shadow values here. */

.pd-card {
  display: flex;
  flex-direction: column;
  gap: var(--pd-space-3);
  padding: var(--pd-space-5);
  background: var(--pd-color-surface-alt);
  border-radius: var(--pd-radius-lg);
  box-sizing: border-box;
}

.pd-card--soft {
  background: var(--pd-color-surface);
  border: 1px solid var(--pd-color-border);
}

.pd-card--interactive {
  transition: transform 160ms ease, box-shadow 160ms ease;
}

.pd-card--interactive:hover {
  transform: translateY(-2px);
  box-shadow: var(--pd-shadow-md);
}

.pd-card--interactive:focus-within {
  box-shadow: var(--pd-shadow-md);
}

.pd-surface-panel {
  padding: var(--pd-space-6);
  background: var(--pd-color-surface);
  border: 1px solid var(--pd-color-border);
  border-radius: var(--pd-radius-md);
}

/* PASS 4BO: shared section-header typography. Page-section modules
 * compose .pd-eyebrow on their kicker element, .pd-section-heading on
 * their section-level headline, and .pd-section-intro on their lede
 * paragraph. Visual styling - font-family/size/weight/line-height,
 * letter-spacing, text-transform, color, max-width - lives here.
 * Tone-aware contrast on dark section backgrounds also lives here.
 *
 * Per-package __eyebrow / __headline / __intro classes survive only
 * as layout placement hooks (margin, text-align, grid) post-PASS-4BO.
 *
 * Hero, blog-list (article-level titles), site-header, and
 * site-footer intentionally do NOT compose these utilities - hero
 * owns its own larger headline treatment via --pd-hero-font-heading,
 * blog-list .pd-blog-list__title is item-level not section-level,
 * and shells are not page-section content. The variant overrides
 * (e.g. content-block --headline--banner, hero banner-wide) stay in
 * place as legitimate variant-specific sizing.
 *
 * Defaults are exposed via CSS custom properties so future Phase 4
 * controls can tune them centrally without touching every package.
 * The variables resolve to the same values used pre-PASS-4BO so
 * adoption is byte-for-byte visually equivalent. */

.pd-eyebrow {
  margin: 0;
  font-family: var(--pd-font-body);
  font-size: var(--pd-eyebrow-font-size, 0.8125rem);
  font-weight: var(--pd-eyebrow-font-weight, 600);
  line-height: var(--pd-eyebrow-line-height, 1.2);
  letter-spacing: var(--pd-eyebrow-letter-spacing, 0.08em);
  text-transform: uppercase;
  color: var(--pd-eyebrow-color, var(--pd-color-accent));
}

.pd-section-heading {
  margin: 0;
  font-family: var(--pd-font-heading);
  font-size: var(--pd-section-heading-font-size, clamp(1.75rem, 3.5vw, 2.5rem));
  line-height: var(--pd-section-heading-line-height, 1.15);
  font-weight: var(--pd-section-heading-font-weight, 700);
  color: var(--pd-section-heading-color, var(--pd-color-text));
}

.pd-section-intro {
  margin: 0;
  font-family: var(--pd-font-body);
  font-size: var(--pd-section-intro-font-size, 1.0625rem);
  line-height: var(--pd-section-intro-line-height, 1.55);
  font-weight: var(--pd-section-intro-font-weight, 400);
  color: var(--pd-section-intro-color, var(--pd-color-muted));
  max-width: var(--pd-section-intro-max-width, 42rem);
}

/* Tone-aware contrast for shared header utilities. When a section
 * sits on a primary or secondary (dark) background, eyebrow / heading
 * / intro flip to surface tones so they stay legible. Per-package
 * tone overrides for these elements are removed in this pass and
 * inherit this contrast rule instead. */
[data-background-tone="primary"] .pd-eyebrow,
[data-background-tone="secondary"] .pd-eyebrow {
  color: var(--pd-color-on-dark);
  opacity: 0.9;
}

[data-background-tone="primary"] .pd-section-heading,
[data-background-tone="secondary"] .pd-section-heading {
  color: var(--pd-color-on-dark);
}

[data-background-tone="primary"] .pd-section-intro,
[data-background-tone="secondary"] .pd-section-intro {
  color: var(--pd-color-on-dark);
  opacity: 0.85;
}

.pd-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.125rem var(--pd-space-2);
  border-radius: 999px;
  background: var(--pd-color-muted-bg);
  color: var(--pd-color-text);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  line-height: 1.6;
}

.pd-step-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  background: var(--pd-color-surface);
  border: 2px solid var(--pd-color-primary);
  color: var(--pd-color-primary);
  font-family: var(--pd-font-heading);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
}

.pd-icon-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--pd-radius-md);
  background: var(--pd-color-muted-bg);
  color: var(--pd-color-primary);
}

.pd-media-frame {
  display: block;
  overflow: hidden;
  border-radius: var(--pd-radius-md);
  background: var(--pd-color-muted-bg);
  box-shadow: var(--pd-shadow-sm);
}

.pd-media-frame--ratio-16x9 {
  aspect-ratio: 16 / 9;
}

.pd-media-frame--ratio-1x1 {
  aspect-ratio: 1 / 1;
}

.pd-media-frame > img,
.pd-media-frame__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (prefers-reduced-motion: reduce) {
  .pd-card--interactive {
    transition: none;
  }
  .pd-card--interactive:hover,
  .pd-card--interactive:focus-within {
    transform: none;
    box-shadow: none;
  }
}

/* Site shell scaffold (used by every site-header / site-footer package).
 *
 * Variant-specific layout, sticky behavior, surface tone, column rules,
 * and details/summary mobile toggling all live in the shell packages'
 * scoped styles.css. The kernel scaffold here keeps just the cross-
 * package primitives: brand row, nav row, link, copy line, mobile
 * details/summary collapse pattern. Modules SHOULD compose these
 * primitives and add scoped overrides under
 * .pd-section--site-header[data-pd-module] /
 * .pd-section--site-footer[data-pd-module]. */

.pd-site-header__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--pd-space-3);
  text-decoration: none;
  color: inherit;
}

.pd-site-header__logo {
  display: block;
  /* PASS 4BM: operator-controlled max-height. The header template
   * emits `style="--pd-header-logo-max-height: <value>;"` on its
   * <header> root for valid enum values; the fallback keeps the
   * legacy 2.5rem default so empty / missing props render the same
   * as before. */
  max-height: var(--pd-header-logo-max-height, 2.5rem);
  width: auto;
}

.pd-site-header__name {
  font-family: var(--pd-font-heading);
  font-weight: 700;
  font-size: 1.0625rem;
  line-height: 1.2;
}

.pd-site-header__tagline {
  font-family: var(--pd-font-body);
  font-size: 0.8125rem;
  color: var(--pd-color-muted);
  line-height: 1.3;
}

.pd-site-header__nav-list {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.25rem var(--pd-space-4);
  list-style: none;
  margin: 0;
  padding: 0;
}

.pd-site-header__nav-list li {
  margin: 0;
  padding: 0;
}

.pd-site-header__nav-list li a,
.pd-site-header__nav-link {
  display: inline-flex;
  align-items: center;
  padding: var(--pd-space-2) var(--pd-space-3);
  text-decoration: none;
  color: inherit;
  font-weight: 500;
  white-space: nowrap;
  border-radius: var(--pd-radius-sm);
}

.pd-site-header__nav-list li a:hover,
.pd-site-header__nav-link:hover,
.pd-site-header__nav-list li a:focus-visible,
.pd-site-header__nav-link:focus-visible {
  background: var(--pd-color-muted-bg);
  color: var(--pd-color-primary);
}

/* Mobile collapse via native <details>/<summary>. No JS dependency.
 *
 * Hamburger / X icon strategy (PASS 4AT):
 *   - Closed state uses ::before only, painted as a 3-bar gradient.
 *   - Open state hides the gradient on ::before, re-paints ::before
 *     as a single solid bar rotated +45deg, and reveals ::after as
 *     the second crossing bar rotated -45deg.
 *
 * The previous implementation rotated a single pseudo-element whose
 * background contained two layered gradients positioned at 'center';
 * because both gradients stacked at the same y-offset and the wrapper
 * was rotated as a whole, the visual result on real browsers was a
 * single line, not an X. Two pseudo-elements with independent
 * rotations renders both diagonals reliably across Chrome / Safari /
 * Firefox.
 *
 * Tap target bumped from 2.5rem to 2.75rem (44px) to meet WCAG 2.5.5
 * Level AAA. */
.pd-site-header__menu-toggle {
  position: relative;
  display: none;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  background: none;
  border: 1px solid var(--pd-color-border);
  border-radius: var(--pd-radius-sm);
  cursor: pointer;
  list-style: none;
  color: inherit;
}

.pd-site-header__menu-toggle::-webkit-details-marker {
  display: none;
}

/* Closed state: ::before paints the hamburger; ::after stays hidden. */
.pd-site-header__menu-toggle::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 1.125rem;
  height: 0.875rem;
  background:
    linear-gradient(currentColor, currentColor) top    / 100% 2px no-repeat,
    linear-gradient(currentColor, currentColor) center / 100% 2px no-repeat,
    linear-gradient(currentColor, currentColor) bottom / 100% 2px no-repeat;
  transform: translate(-50%, -50%);
}

.pd-site-header__menu-toggle::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 1.375rem;
  height: 2px;
  background: currentColor;
  display: none;
}

/* Open state: rotate ::before into one diagonal, reveal ::after as
 * the crossing diagonal. */
.pd-site-header__menu[open] .pd-site-header__menu-toggle::before {
  width: 1.375rem;
  height: 2px;
  background: currentColor;
  transform: translate(-50%, -50%) rotate(45deg);
}

.pd-site-header__menu[open] .pd-site-header__menu-toggle::after {
  display: block;
  transform: translate(-50%, -50%) rotate(-45deg);
}

/* Active / current page styling for header nav.
 *
 * Applies to both wp_nav_menu output (which emits .current-menu-item
 * / .current_page_item / .current-menu-parent / .current-menu-ancestor
 * on the <li>) and the payload-fallback renderer (which adds
 * aria-current="page" on the matching <a> via PHP path comparison).
 *
 * Indicator is non-color: text-decoration underline + bold weight, so
 * it remains visible on dark surfaces (transparent header over hero
 * imagery, or topbar primary background) where the primary color
 * token would risk low contrast. The primary color is layered on top
 * for emphasis on light surfaces; it falls back to currentColor where
 * primary would be invisible. */
.pd-site-header__nav-list .current-menu-item > a,
.pd-site-header__nav-list .current_page_item > a,
.pd-site-header__nav-list .current-menu-parent > a,
.pd-site-header__nav-list .current-menu-ancestor > a,
.pd-site-header__nav-list a[aria-current="page"],
.pd-site-header__nav-link[aria-current="page"] {
  color: var(--pd-color-primary);
  font-weight: 700;
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.3em;
}

/* Topbar context (primary surface): primary color would disappear on
 * primary background, so let the active item inherit the on-dark
 * color and rely on underline + weight as the indicator. */
.pd-section--site-header[data-pd-module] .pd-site-header__topbar .pd-site-header__nav-list .current-menu-item > a,
.pd-section--site-header[data-pd-module] .pd-site-header__topbar .pd-site-header__nav-list a[aria-current="page"],
.pd-section--site-header[data-pd-module] .pd-site-header__topbar .pd-site-header__nav-link[aria-current="page"] {
  color: inherit;
}

.pd-site-footer__copy {
  margin: 0;
  font-size: 0.875rem;
  color: var(--pd-color-muted);
}

.pd-site-footer__tagline {
  margin: 0;
  font-size: 0.9375rem;
  color: var(--pd-color-muted);
  line-height: 1.5;
  max-width: 32rem;
}

.pd-site-footer__contact-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--pd-space-2);
  font-size: 0.875rem;
}

.pd-site-footer__contact-list li {
  margin: 0;
}

.pd-site-footer__contact-list a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 150ms ease;
}

.pd-site-footer__contact-list a:hover,
.pd-site-footer__contact-list a:focus-visible {
  border-bottom-color: currentColor;
}

.pd-site-footer__nav-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--pd-space-2);
  font-size: 0.9375rem;
}

.pd-site-footer__nav-list li {
  margin: 0;
}

.pd-site-footer__nav-list li a,
.pd-site-footer__nav-link {
  text-decoration: none;
  color: inherit;
  border-bottom: 1px solid transparent;
  transition: border-color 150ms ease, color 150ms ease;
}

.pd-site-footer__nav-list li a:hover,
.pd-site-footer__nav-link:hover,
.pd-site-footer__nav-list li a:focus-visible,
.pd-site-footer__nav-link:focus-visible {
  border-bottom-color: currentColor;
}

/* Active / current page styling for footer nav.
 *
 * Mirrors the header pattern: covers both wp_nav_menu .current-* /
 * .current_page_item classes and the payload-fallback aria-current
 * attribute. Border + weight gives a non-color indicator that works
 * on every footer surface tone (surface, surface-alt, primary,
 * secondary, transparent). currentColor border + bold weight means
 * the indicator is visible on dark surfaces without needing a
 * surface-scoped override - the underline color flips with the
 * surface text color automatically. */
.pd-site-footer__nav-list .current-menu-item > a,
.pd-site-footer__nav-list .current_page_item > a,
.pd-site-footer__nav-list .current-menu-parent > a,
.pd-site-footer__nav-list .current-menu-ancestor > a,
.pd-site-footer__nav-list a[aria-current="page"],
.pd-site-footer__nav-link[aria-current="page"] {
  font-weight: 700;
  border-bottom-color: currentColor;
}

@media (prefers-reduced-motion: reduce) {
  .pd-site-footer__contact-list a {
    transition: none;
  }
}

/* Site-wide social link row.
 *
 * Used by both site-header and site-footer shells via
 * phasma_v3_render_social_links() (theme/inc/social-links.php). Icons
 * use currentColor and inherit the chrome's own color, so dark/primary
 * surfaces (header transparent over hero, footer surface=primary) get
 * matching icon color automatically. Icon size defaults to 24px and
 * is set inline as width/height attrs by the renderer; CSS only
 * controls layout, focus, and hover. */
.pd-social-links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--pd-space-2);
}

.pd-social-links__item {
  display: inline-flex;
}

.pd-social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--pd-radius-sm);
  color: inherit;
  text-decoration: none;
  transition: color .12s ease, background-color .12s ease, transform .12s ease;
}

.pd-social-link:hover {
  color: var(--pd-color-primary);
  background: var(--pd-color-muted-bg);
}

.pd-social-link:focus-visible {
  outline: 2px solid var(--pd-color-primary);
  outline-offset: 2px;
}

.pd-social-link__icon {
  display: inline-flex;
  width: 1.25rem;
  height: 1.25rem;
  line-height: 1;
}

.pd-social-link__icon svg {
  width: 100%;
  height: 100%;
  display: block;
}

.pd-visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  .pd-social-link {
    transition: none;
  }
}

/* Page layout */
.pd-preview-route {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.pd-main {
  flex: 1;
}
