/* ============================================================
   PAGES — Blog / archive / single / 404 / misc inner pages
   ============================================================ */

/* The home page sits on plain white rather than the body's off-white
   --color-bg; individual sections paint their own grounds over it. */
.page-home {
  background: #ffffff;
}

/* ── Blog / Archive ─────────────────────────────────────────── */
.sh-archive { padding: 12.5rem 0 var(--space-24); }

.sh-archive__header { margin-bottom: var(--space-12); }

.sh-archive__headline {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4vw, 3rem);
  font-weight: 600;
  color: var(--color-heading);
  line-height: 1.1;
}

.sh-archive__desc {
  margin-top: var(--space-4);
  font-size: var(--text-lg);
  color: var(--color-muted);
}

.sh-archive__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(21.25rem, 1fr));
  gap: var(--space-8);
}

.sh-archive__empty { text-align: center; padding: var(--space-16) 0; }

.sh-archive__empty h2 {
  font-size: var(--text-3xl);
  color: var(--color-heading);
  margin-bottom: var(--space-4);
}

/* Post card */
.sh-post-card {
  background: #fff;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-card);
  transition: var(--transition-base);
  display: flex;
  flex-direction: column;
}

.sh-post-card:hover { box-shadow: var(--shadow-nav); }

.sh-post-card__thumb {
  display: block;
  aspect-ratio: 16/9;
  overflow: hidden;
}

.sh-post-card__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.4s ease;
}

.sh-post-card:hover .sh-post-card__thumb img { transform: scale(1.03); }

.sh-post-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-6);
  flex: 1;
}

.sh-post-card__date {
  font-size: 0.8125rem;
  color: var(--color-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.sh-post-card__title {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 600;
  color: var(--color-heading);
  line-height: 1.3;
}

.sh-post-card__title a { color: inherit; }
.sh-post-card__title a:hover { color: var(--color-primary); }

.sh-post-card__excerpt {
  font-size: var(--text-base);
  color: var(--color-muted);
  line-height: 1.6;
  flex: 1;
}

/* Pagination */
.nav-links {
  display: flex;
  justify-content: center;
  gap: var(--space-2);
  margin-top: var(--space-12);
  flex-wrap: wrap;
}

.nav-links a,
.nav-links span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.75rem;
  height: 2.75rem;
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: 500;
  border: 1px solid var(--color-border);
  color: var(--color-heading);
  transition: var(--transition-base);
}

.nav-links a:hover { background: var(--color-bg-section); }
.nav-links .current { background: var(--color-primary); color: #fff; border-color: var(--color-primary); }

/* ── Generic page ───────────────────────────────────────────── */
.sh-page { padding: 12.5rem 0 var(--space-24); }

.sh-page__header { margin-bottom: var(--space-10); }

.sh-page__hero-image {
  border-radius: var(--radius-xl);
  overflow: hidden;
  margin-bottom: var(--space-8);
  aspect-ratio: 21/9;
}

.sh-page__hero-image img { width: 100%; height: 100%; object-fit: cover; }

.sh-page__headline {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4vw, 3.25rem);
  font-weight: 600;
  color: var(--color-heading);
  line-height: 1.1;
}

/* wp_content typography */
.wp-content { max-width: 47.5rem; }

.wp-content h2 {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 600;
  color: var(--color-heading);
  margin: var(--space-10) 0 var(--space-4);
}

.wp-content h3 {
  font-size: var(--text-xl);
  font-weight: 600;
  color: var(--color-heading);
  margin: var(--space-8) 0 var(--space-3);
}

.wp-content p { margin-bottom: var(--space-5); }

.wp-content ul,
.wp-content ol {
  padding-left: var(--space-6);
  margin-bottom: var(--space-5);
  list-style: disc;
}

.wp-content li { margin-bottom: var(--space-2); }

.wp-content a {
  color: var(--color-primary);
  text-decoration: underline;
}

.wp-content a:hover { color: var(--color-blue-deep); }

/* ── Legal pages (Privacy Policy, HIPAA Notice) ───────────────── Plain post_content pages rendered through page.php, so everything here hangs off.wp-content rather than a section component. */

.wp-content table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: var(--space-6);
  font-size: var(--text-md);
}

.wp-content table th,
.wp-content table td {
  text-align: left;
  vertical-align: top;
  padding: 0.875rem 1rem;
  border-bottom: 1px solid var(--color-border);
}

.wp-content table thead th {
  font-weight: 600;
  color: var(--color-heading);
  background: var(--color-bg);
}

/* The label column of a meta/rights table: a row heading, not a
   column heading, so it keeps body weight but takes the accent
   colour to separate it from the value beside it. */
.wp-content table tbody th[scope="row"] {
  font-weight: 600;
  color: var(--color-heading);
  width: 34%;
}

.sh-legal-intro {
  font-size: var(--text-md);
  color: var(--color-muted);
}

.sh-legal-callout {
  padding: 1.25rem 1.5rem;
  margin-bottom: var(--space-6);
  border-left: 3px solid var(--color-primary);
  border-radius: 0 0.5rem 0.5rem 0;
  background: var(--color-bg);
}

/* Last paragraph in a callout should not carry the standard
   paragraph margin into the box's own padding. */
.sh-legal-callout > p:last-child { margin-bottom: 0; }

/* The emergency / "review carefully" boxes — same shape, urgent
   accent, since these are the ones a reader must not skim past. */
.sh-legal-callout--urgent {
  border-left-color: var(--color-error, #c0392b);
}

@media (max-width: 640px) {
  /* Two columns of legal prose do not fit a phone: stack each row
     into label-above-value instead of letting the table scroll
     sideways, which readers of a legal notice will not discover. */
  .wp-content table,
  .wp-content table tbody,
  .wp-content table tr,
  .wp-content table th,
  .wp-content table td {
    display: block;
    width: 100%;
  }

  .wp-content table thead { display: none; }

  .wp-content table tr {
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--color-border);
  }

  .wp-content table th,
  .wp-content table td {
    padding: 0.25rem 0;
    border-bottom: 0;
  }

  .wp-content table tbody th[scope="row"] { width: 100%; }
}

/* ── Single post ────────────────────────────────────────────── */
.sh-single { padding: 12.5rem 0 var(--space-24); }

.sh-single__inner { max-width: 50rem; }

.sh-single__meta {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: 0.8125rem;
  color: var(--color-muted);
  margin-bottom: var(--space-5);
}

.sh-single__meta a { color: var(--color-muted); }

.sh-single__headline {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 4vw, 3rem);
  font-weight: 700;
  color: var(--color-heading);
  line-height: 1.1;
  margin-bottom: var(--space-8);
}

.sh-single__hero-image {
  border-radius: var(--radius-xl);
  overflow: hidden;
  margin-bottom: var(--space-10);
  aspect-ratio: 16/9;
}

.sh-single__hero-image img { width: 100%; height: 100%; object-fit: cover; }

.sh-single__body { margin-bottom: var(--space-12); }

.sh-single__footer .nav-links { justify-content: space-between; margin-top: 0; }

/* ── 404 ────────────────────────────────────────────────────── */
.sh-404 { padding: 13.75rem 0 var(--space-24); text-align: center; }

.sh-404__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
  max-width: 37.5rem;
  margin: 0 auto;
}

.sh-404__code {
  font-size: clamp(4rem, 12vw, 8rem);
  font-family: var(--font-display);
  font-weight: 800;
  color: var(--color-primary);
  opacity: 0.2;
  letter-spacing: -0.03em;
  line-height: 1;
}

.sh-404__headline {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3vw, 2.5rem);
  font-weight: 600;
  color: var(--color-heading);
  line-height: 1.1;
}

.sh-404__body {
  font-size: var(--text-lg);
  color: var(--color-muted);
  line-height: 1.6;
}

.sh-404__actions {
  display: flex;
  gap: var(--space-4);
  flex-wrap: wrap;
  justify-content: center;
}

/* Search form */
.search-form {
  display: flex;
  gap: var(--space-3);
  width: 100%;
  max-width: 26.25rem;
}

.search-form label { flex: 1; }

.search-form input[type="search"] {
  width: 100%;
  height: 3rem;
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-size: var(--text-base);
  color: var(--color-text);
  background: #fff;
  outline: none;
  transition: var(--transition-base);
}

.search-form input[type="search"]:focus { border-color: var(--color-primary); }

.search-form button[type="submit"] {
  height: 3rem;
  padding: 0 var(--space-5);
  background: var(--color-primary);
  color: #fff;
  border: none;
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: var(--transition-base);
}

.search-form button[type="submit"]:hover { background: var(--color-primary-hover); }

/* ── Map embed ──────────────────────────────────────────────── */
.sh-map { width: 100%; height: 26.25rem; overflow: hidden; }

.sh-map iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* MOTION SYSTEM ------------------------------------------------------------ One reveal primitive for the whole theme. */
.sh-motion .sh-card-grid__item,
.sh-motion .sh-locations-card,
.sh-motion .sh-loc-tile,
.sh-motion .sh-story-card,
.sh-motion .sh-vm__card,
/* The banner's media panel is NOT revealed: it is display:none below the wide breakpoint, and a zero-size element can never intersect, so the observer would never fire and it would sit armed at opacity:0 forever. */
.sh-motion .sh-banner__intake-content,
.sh-motion .sh-step-card,
.sh-motion .sh-team-card,
.sh-motion .sh-cat-card,
.sh-motion .sh-cd-card,
.sh-motion .sh-audience-card,
.sh-motion .sh-why__col,
.sh-motion .sh-who-we-are__gallery,
.sh-motion .sh-ic-card,
.sh-motion .sh-vision__feature,
.sh-motion .sh-stat-bar__item,
.sh-motion .sh-cta-band__inner,
.sh-motion .sh-conditions__header,
.sh-motion .sh-conditions__stage,
.sh-motion .sh-eligibility__photo,
.sh-motion .sh-loc-fact,
.sh-motion .sh-loc-hours,
.sh-motion .sh-loc-services__item,
.sh-motion .sh-loc-about__inner,
.sh-motion .sh-insurance-band__panel,
/* Refer a Patient */
.sh-motion .sh-emergency-band,
.sh-motion .sh-accept__facts,
.sh-motion .sh-accept__media,
.sh-motion .sh-accept-card,
.sh-motion .sh-accept__urgent,
.sh-motion .sh-faq-section .sh-content-block__heading,
.sh-motion .sh-faq,
.sh-motion .sh-wizard--inline .sh-wizard__frame {
  opacity: 0;
  /* Direction comes from variables so a group can enter from the side instead of below WITHOUT another `transform` declaration. */
  transform: translate(var(--sh-enter-x, 0px), var(--sh-enter-y, 1.5rem)) scale(var(--sh-enter-scale, 1));
  transition:
    opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1),
    transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
  /* Stagger within a group; --sh-i is set once by JS */
  transition-delay: calc(var(--sh-i, 0) * 60ms);
}


/* Section headers get a gentler, shorter rise than their cards */
.sh-motion .sh-why__header,
.sh-motion .sh-who-we-are__header,
.sh-motion .sh-icon-cards__header,
.sh-motion .sh-story-cards__header,
.sh-motion .sh-steps__left,
.sh-motion .sh-eligibility__header,
.sh-motion .sh-loc-services__head {
  opacity: 0;
  transform: translateY(1rem);
  transition:
    opacity 0.45s cubic-bezier(0.4, 0, 0.2, 1),
    transform 0.45s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Declared AFTER every hidden state above: these selectors carry the same specificity, so source order is what decides the winner. */
.sh-motion .is-visible {
  opacity: 1;
  transform: none;
}

.sh-motion .sh-faq-section .sh-content-block__heading.is-visible,
.sh-motion .sh-wizard--inline .sh-wizard__frame.is-visible {
  opacity: 1;
  transform: none;
}

/* Show all content immediately when reduced motion is enabled. */
@media (prefers-reduced-motion: reduce) {
  .sh-motion .sh-card-grid__item,
  .sh-motion .sh-locations-card,
  .sh-motion .sh-loc-tile,
  .sh-motion .sh-story-card,
  .sh-motion .sh-vm__card,
  .sh-motion .sh-banner__intake-content,
  .sh-motion .sh-step-card,
  .sh-motion .sh-team-card,
  .sh-motion .sh-cat-card,
  .sh-motion .sh-cd-card,
  .sh-motion .sh-audience-card,
  .sh-motion .sh-why__col,
  .sh-motion .sh-who-we-are__gallery,
  .sh-motion .sh-ic-card,
  .sh-motion .sh-vision__feature,
  .sh-motion .sh-stat-bar__item,
  .sh-motion .sh-cta-band__inner,
  .sh-motion .sh-conditions__header,
  .sh-motion .sh-conditions__stage,
  .sh-motion .sh-eligibility__photo,
  .sh-motion .sh-why__header,
  .sh-motion .sh-who-we-are__header,
  .sh-motion .sh-icon-cards__header,
  .sh-motion .sh-story-cards__header,
  .sh-motion .sh-steps__left,
  .sh-motion .sh-eligibility__header,
  .sh-motion .sh-loc-fact,
  .sh-motion .sh-loc-hours,
  .sh-motion .sh-loc-services__item,
  .sh-motion .sh-loc-services__head,
  .sh-motion .sh-loc-about__inner,
  .sh-motion .sh-insurance-band__panel,
  .sh-motion .sh-emergency-band,
  .sh-motion .sh-accept__facts,
  .sh-motion .sh-accept__media,
  .sh-motion .sh-accept-card,
  .sh-motion .sh-accept__urgent,
  .sh-motion .sh-faq-section .sh-content-block__heading,
  .sh-motion .sh-faq,
  .sh-motion .sh-wizard--inline .sh-wizard__frame {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ── Hover polish (CSS only — no JS, no layout thrash) ──────── */

/* Photos inside a clipped frame ease in slightly on hover */
.sh-arch img {
  transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

@media (hover: hover) and (pointer: fine) {
  .sh-arch:hover img { transform: scale(1.04); }

  /* Icon cards lift a touch to read as tappable */
  .sh-ic-card { transition: transform 0.3s ease, box-shadow 0.3s ease; }
  .sh-ic-card:hover { transform: translateY(-3px); }

  /* The arrow in pill CTAs nudges toward its direction. The icon-pill
     variants centre their circle with translateY(-50%) (it is
     absolutely positioned — see base.css), so the nudge has to carry
     that through or the circle drops half its height on hover. */
  .sh-btn .sh-btn__icon { transition: transform 0.25s ease; }
  .sh-btn:hover .sh-btn__icon { transform: translateX(2px); }

  .sh-btn--pill-white:hover .sh-btn__icon,
  .sh-btn--pill-blue:hover .sh-btn__icon,
  .sh-btn--pill-plain:hover .sh-btn__icon {
    transform: translateY(-50%) translateX(2px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .sh-cc-card img,
  .sh-arch img,
  .sh-ic-card,
  .sh-btn .sh-btn__icon { transition: none; }

  .sh-cc-card:hover img,
  .sh-arch:hover img,
  .sh-ic-card:hover,
  .sh-btn:hover .sh-btn__icon { transform: none; }

  /*...except the centring transform, which is layout rather than
     motion — dropping it would misplace the circle, not still it. */
  .sh-btn--pill-white .sh-btn__icon,
  .sh-btn--pill-blue .sh-btn__icon,
  .sh-btn--pill-plain .sh-btn__icon,
  .sh-btn--pill-white:hover .sh-btn__icon,
  .sh-btn--pill-blue:hover .sh-btn__icon,
  .sh-btn--pill-plain:hover .sh-btn__icon {
    transform: translateY(-50%);
  }
}

@media (max-width: 768px) {
  .sh-archive__grid { grid-template-columns: 1fr; }
  .sh-map { height: 17.5rem; }
}

/* LOCATIONS PAGE Renders on pure white rather than the site's default tinted background, so the light grey map panel reads as a panel. */
body.page-template-page-locations {
  background-color: #fff;
}

/* ============================================================
   SERVICE PAGE (single-starfish_service.php)
   ============================================================ */
/* Article layout, driven by three numbers so they can be tuned in one place: the page gutter, where the prose column starts, and how wide it runs. */
.sh-service {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  /* Horizontal inset comes from --container, same as every other
     container — see.sh-container in base.css. */
  padding: 4rem 0 5rem;
  display: grid;
  grid-template-columns: 20rem 1fr;
  gap: 4rem;
  align-items: start;
}

/* FAQs and anything else that reads as a page-level section rather than part of the article render here, outside the two-column row — see the split in service-content.php. */
.sh-service-full {
  width: 100%;
  max-width: var(--container);
  /* This wrapper exists solely to release the sticky TOC before a page/screen-width block. */
  margin: 0 auto;
  padding: 0;
}

/* The row hands its bottom spacing to.sh-service-full when one
   follows, so the two do not stack their padding into a gap. */
.sh-service--has-full {
  padding-bottom: 0;
}

/* No.sh-service__toc in the DOM at all (table of contents hidden,
   either automatically — under 2 headed sections — or forced off via
   the Hide Table of Contents toggle) — without this,.sh-service__content
   would be the grid's only child and fall into the first (20rem) track
   instead of the second, capping the whole page's content at 20rem wide. */
.sh-service--no-toc {
  grid-template-columns: 1fr;
}

/* Stays in view for the whole scroll of the article. This only works
   because no ancestor is a scroll container — see the overflow-x note
   on body in base.css. */
.sh-service__toc {
  position: sticky;
  top: 9rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 0.75rem;
  padding: 1.25rem 1rem;
  /* The list can outgrow a short viewport once a service has many
     sections; scroll it inside the card rather than letting the card
     run past the fold with its tail unreachable. */
  max-height: calc(100vh - 8rem);
  overflow-y: auto;
}

.sh-service__toc-label {
  font-size: var(--text-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-muted);
  margin: 0 0 0.75rem 0.75rem;
}

.sh-service__toc-list {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}

/* Desktop shows the link list; the listbox is the narrow-screen
   alternative and stays out of the way (and out of the accessibility
   tree) until the breakpoint below swaps them. */
.sh-service__toc-select {
  display: none;
}

.sh-service__toc a {
  display: block;
  padding: 0.5rem 0.75rem;
  border-radius: 0.5rem;
  font-size: var(--text-base);
  font-weight: 500;
  color: var(--color-text);
  transition: var(--transition-base);
}

.sh-service__toc a:hover {
  color: var(--color-primary);
  background: var(--color-bg-section);
}

/* Which section you are actually reading. Set by main.js. */
.sh-service__toc a.is-active {
  color: var(--color-primary);
  font-weight: 600;
  background: #e6f2f9;
}

@supports (color: color-mix(in srgb, red 50%, white)) {
  .sh-service__toc a.is-active {
    background: color-mix(in srgb, var(--color-primary) 12%, #fff);
  }
}

.sh-service__content {
  min-width: 0;
}

/* Shared with the Service Category page — both render through
   content-blocks.php, so one set of rules covers both contexts. */
.sh-content-block {
  /* One reading scale for the whole article, set here and inherited by every block type, so prose, bullets, steps and FAQ answers are the same size by construction rather than by four rules that have to be kept in step. */
  --prose-body:    1.0625rem;
  --prose-heading: 1.625rem;

  scroll-margin-top: 6rem;
  /* No margin here on purpose — the "Space below" field's default is
     now explicitly 'none' for a content block (see
     starfish_acf_spacing_field()'s $default argument at each of its
     call sites), so an untouched block should render with none,
     rather than this component quietly supplying 2.5rem the field
     never actually chose. Spacing between blocks is now entirely an
     editorial choice made per block via that field, not a value
     baked into the component. */
  margin-bottom: 0;
  /* Vertical breathing room every block gets by default, background or not. */
  padding-block: clamp(2.75rem, 5vw, 4rem);
  font-size: var(--prose-body);
}

/* Optional per-block background — same colour choices a Banner
   offers (see starfish_block_bg_style()). --block-bg/--block-fg are
   only ever set inline when an editor actually picks one, so a plain
   block with no override renders with no panel at all. */
.sh-content-block--bg {
  background: var(--block-bg);
  color: var(--block-fg);
  /* Inline only — the vertical padding comes from.sh-content-block itself, so one value governs the rhythm of plain and panelled blocks alike. */
  padding-inline: clamp(2rem, 4vw, 3rem);
  border-radius: 2.5rem;
}

/* Full Screen (see starfish_block_width_mode()) needs its own
   horizontal inset —.sh-bw-screen's own padding-inline centres the
   content back onto the page measure once the background has run to
   the viewport edge — rather than the plain panel padding above,
   which would otherwise win here since this file loads after
   sections.css. Vertical padding stays the panel's own; only the
   sides need to change with the width. */

/* Full Screen on an Embed block: unlike text/FAQ blocks (where the
   only thing "full screen" changes is a BACKGROUND running edge to
   edge — the copy itself stays capped at the page measure on
   purpose, for readability), the whole point of Full Screen on an
   embed is the embed itself going edge to edge — a video or form has
   no readability argument for staying narrow..sh-bw-screen's own
   padding-inline exists to recentre content back onto the page
   measure once its BOX runs to the viewport edge; negating exactly
   that padding on the embed child is what lets the iframe use the
   full-bleed box instead of being pulled back in by it. The heading/
   subheading above it, if any, keep the padding and stay capped. */
.sh-content-block.sh-bw-screen > .sh-embed {
  /* The same viewport-breakout formula.sh-bw-screen itself uses on the outer block, applied one level deeper. */
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}

.sh-content-block--bg.sh-bw-screen {
  padding-inline: max(var(--gutter), calc(50vw - var(--container) / 2));
  /* A rounded corner has nothing to sit against once the background
     runs to the screen edge — same reasoning as the Banner's own
     screen-width reset. */
  border-radius: 0;
}

.sh-content-block--bg .sh-content-block__heading,
.sh-content-block--bg .sh-content-block__subheading,
.sh-content-block--bg .sh-content-block__body,
.sh-content-block--bg .sh-content-block__text {
  color: inherit;
}

.sh-content-block__heading {
  font-family: var(--font-display);
  font-size: var(--prose-heading);
  font-weight: 700;
  /* Tighter than body copy: display type at this size opens up gaps
     between lines if it keeps the inherited 1.5. */
  line-height: 1.25;
  /* Dark by default. These are section headings inside an article, so
     they read as structure; the brand blue made every one of them
     look like a link. Per-block opt-in below. */
  color: var(--color-heading);
  margin-bottom: 1rem;
}

.sh-content-block__heading--primary {
  color: var(--color-blue-deep);
}

.sh-content-block__body {
  font-size: var(--prose-body);
  line-height: 1.7;
  color: var(--color-text);
}

/* Prose spacing. */
.sh-content-block__body > p {
  margin-block: 0 1.125em;
}

.sh-content-block__body > *:last-child {
  margin-bottom: 0;
}

.sh-content-block__body > *:first-child {
  margin-top: 0;
}

.sh-content-block__body ul,
.sh-content-block__body ol {
  padding-left: 1.25rem;
  margin-block: 0 1.125em;
}

/* The reset strips list markers globally; inside prose they carry
   meaning, so put them back. */
.sh-content-block__body ul { list-style: disc; }
.sh-content-block__body ol { list-style: decimal; }

.sh-content-block__body li {
  margin-block: 0.35em;
}

.sh-content-block__body li::marker {
  color: var(--color-primary);
}

/* A list nested inside a list item should not restart the full
   paragraph gap above itself. */
.sh-content-block__body li > ul,
.sh-content-block__body li > ol {
  margin-block: 0.35em 0;
}

.sh-content-block__body strong { font-weight: 700; color: var(--color-heading); }
.sh-content-block__body em     { font-style: italic; }

/* Optional closing button on Text, List, Step List and Image + Text
   blocks — same top gap regardless of what came right before it
   (a paragraph, a list, a numbered step). */
.sh-content-block__cta { margin-top: 1.5rem; }

/* The canonical inline-link treatment: primary colour + underline, everywhere a link can appear in content. */
.sh-content-block__body a,
.sh-content-block__subheading a,
.sh-steps-list__desc a,
.sh-steps-list__title a,
.sh-bullets__item a,
.sh-faq__a a,
.sh-faq__q-text a,
.sh-card-grid__blurb a,
.sh-card-grid__title a,
.sh-service-inline__title a,
.sh-service-inline__body a {
  color: var(--color-primary);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

/* Intro line shared by List, Step List and FAQs. */
.sh-content-block__subheading {
  margin: -0.5rem 0 1.5rem;
  color: #595959;
  line-height: 1.6;
  max-width: 48rem;
}

/* Centering the TEXT inside a box that is itself pinned to the left (max-width with no auto margin, above) does not read as centered — the narrow box sits left, and the text centers within that narrow box rather than within the full block. */
.sh-content-block__subheading[style*="text-align:center"] {
  margin-left: auto;
  margin-right: auto;
}

.sh-content-block__subheading[style*="text-align:right"] {
  margin-left: auto;
  margin-right: 0;
}

/* ── List block ──────────────────────────────────────────────── */
.sh-bullets {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  list-style: none;
  padding: 0;
  margin: 0;
}

.sh-bullets__item {
  position: relative;
  padding-left: 1.3125rem;
  line-height: 1.6;
  color: var(--color-text);
}

/* Drawn rather than a list-marker so the dot keeps its size and
   colour regardless of the item's font-size, and stays put on a
   wrapped line. */
.sh-bullets__item::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.5625rem;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--color-primary);
}

/* ── Step list block ─────────────────────────────────────────── */
.sh-steps-list {
  /* The counter is what puts numbers on screen — nothing is typed, so
     reordering or inserting a step renumbers the rest for free. */
  counter-reset: sh-step;
  display: flex;
  flex-direction: column;
  gap: 0.875rem;
  list-style: none;
  padding: 0;
  margin: 0;
}

.sh-steps-list__item {
  counter-increment: sh-step;
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 0.75rem;
  padding: 1.125rem 1.25rem;
}

.sh-steps-list__item::before {
  content: counter(sh-step);
  flex-shrink: 0;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-bg-section);
  color: var(--color-primary);
  font-size: var(--text-sm);
  font-weight: 700;
  line-height: 1;
}

.sh-steps-list__title {
  font-weight: 700;
  color: var(--color-heading);
  margin: 0;
}

/* A step with no description: the title is the whole step, so it is
   body copy, not a label for something beneath it. Bolding it there
   just reads as emphasis for its own sake. :only-child means this
   follows the content automatically — nothing to set per step. */
.sh-steps-list__text > .sh-steps-list__title:only-child {
  font-weight: 400;
}

.sh-steps-list__desc {
  margin: 0.25rem 0 0;
  color: var(--color-text);
  line-height: 1.5;
}

/* ── FAQs block — <details>/<summary> accordion ──────────────── */
.sh-faq-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.sh-faq {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 0.75rem;
}

.sh-faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.375rem 1.5rem;
  cursor: pointer;
  font-weight: 700;
  color: var(--color-heading);
  list-style: none;          /* Firefox */
}

/* The default disclosure triangle, replaced by the +/− below. */
.sh-faq__q::-webkit-details-marker { display: none; }

.sh-faq__q:hover { color: var(--color-primary); }

@media (hover: hover) and (pointer: fine) {
  .sh-accept-card { transition: transform 0.3s ease, box-shadow 0.3s ease; }
  .sh-accept-card:hover { transform: translateY(-3px); box-shadow: 0 0.75rem 1.75rem rgba(16, 68, 95, 0.13); }

  .sh-accept__urgent-link { transition: transform 0.2s ease-out; }
  .sh-accept__urgent-link:hover { transform: translateX(2px); }
}

@media (prefers-reduced-motion: reduce) {
  .sh-accept-card, .sh-accept__urgent-link { transition: none; }
  .sh-accept-card:hover, .sh-accept__urgent-link:hover { transform: none; box-shadow: none; }
}

.sh-faq__q:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: -2px;
  border-radius: 0.75rem;
}

/* A plus that loses its vertical stroke when open, so one element
   covers both states and there is no icon swap to keep in sync. */
.sh-faq__icon {
  position: relative;
  flex-shrink: 0;
  width: 14px;
  height: 14px;
}

.sh-faq__icon::before,
.sh-faq__icon::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 14px;
  height: 2px;
  background: var(--color-primary);
  transform: translate(-50%, -50%);
  transition: var(--transition-base);
}

.sh-faq__icon::after {
  transform: translate(-50%, -50%) rotate(90deg);
}

.sh-faq[open] .sh-faq__icon::after {
  transform: translate(-50%, -50%) rotate(0deg);
  opacity: 0;
}

.sh-faq__a {
  padding: 0 1.5rem 1.375rem;
  color: var(--color-text);
  line-height: 1.6;
}

/* ── Image + Text block ──────────────────────────────────────── */
.sh-content-block--image-text {
  display: flex;
  align-items: center;
  gap: 3rem;
}

.sh-content-block--image-left {
  flex-direction: row-reverse;
}

.sh-content-block--image-text .sh-content-block__image {
  flex: 1;
  min-width: 0;
  border-radius: var(--radius-2xl);
  overflow: hidden;
}

.sh-content-block--image-text .sh-content-block__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.sh-content-block--image-text .sh-content-block__text {
  flex: 1;
  min-width: 0;
}

@media (max-width: 768px) {
  .sh-content-block--image-text,
  .sh-content-block--image-left {
    flex-direction: column;
  }
}

/* ── Inline mode: a Category child rendered directly on its
   category page instead of at its own URL ── */
.sh-service-inline {
  max-width: var(--container);
  margin: 0 auto 3rem;
  padding: 0 var(--gutter);
  scroll-margin-top: 6rem;
}

.sh-service-inline__title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--color-blue-deep);
  margin-bottom: 0.5rem;
}

.sh-service-inline__body {
  font-size: var(--text-base);
  line-height: 1.6;
  color: var(--color-text);
}

/* ── Shared card grid (card-grid.php) — the Category page's "services
   in this category" list, a Cards Block, and a Condition's How We
   Can Help section all render through this one partial and share
   these rules. ── */
/* A real grid with explicit columns, not flex-wrap. That matters for
   an empty track: with grid-template-columns: repeat(3, 1fr), 2 cards
   (or 1) still only occupy 2 (or 1) of the 3 defined column tracks —
   the leftover track holds its share of the width and simply stays
   empty, rather than being redistributed to the cards present. Flex
   can't do that: a flex item with flex-grow can only be sized by what
   flex items exist, so 2 cards in a flex row necessarily grow to fill
   the row. Grid is what gives "always the same card width" and
   "exactly 3 per row on desktop" at once, since both come from the
   same fixed 3-column track definition — narrower steps down the
   column count instead (see the media queries below). */
.sh-card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
  margin-top: 1.5rem;
}

.sh-card-grid__item {
  display: flex;
  flex-direction: column;
  padding: 1.75rem;
  border: 1px solid var(--color-border);
  border-radius: 1rem;
  background: var(--color-surface);
  transition: var(--transition-base);
}

.sh-card-grid__item:hover {
  border-color: var(--color-primary);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06);
}

/* ── Card with an icon ────────────────────── A card whose Service/Category has a Card Icon set takes a different shape: its top-left corner sweeps inward around a circular badge, leaving a gap of page background between the two. */
.sh-card-grid__item--has-icon {
  --card-icon-size: 3.75rem;
  /* Corner-piece box, proportional to the badge so the whole
     treatment scales together. */
  --card-notch-w: calc(var(--card-icon-size) * 2.084);
  --card-notch-h: calc(var(--card-icon-size) * 1.815);
  position: relative;
  background: transparent;
  border: 0;
  padding-top: calc(var(--card-icon-size) * 1.73);
}

.sh-card-grid__item--has-icon::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--color-surface);
  border-radius: 1.625rem;
  transition: var(--transition-base);

  -webkit-mask-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 124 108' preserveAspectRatio='none'%3E%3Cpath d='M77.25 47.41C76.46 21.46 97.27 0 123.23 0L124 0L124 108L0 108L0 106C0 91.64 11.64 80 26 80L51.44 80C66.11 80 77.88 67.87 77.43 53.21Z' fill='%23fff'/%3E%3C/svg%3E"),
    linear-gradient(#000, #000),
    linear-gradient(#000, #000);
  mask-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 124 108' preserveAspectRatio='none'%3E%3Cpath d='M77.25 47.41C76.46 21.46 97.27 0 123.23 0L124 0L124 108L0 108L0 106C0 91.64 11.64 80 26 80L51.44 80C66.11 80 77.88 67.87 77.43 53.21Z' fill='%23fff'/%3E%3C/svg%3E"),
    linear-gradient(#000, #000),
    linear-gradient(#000, #000);

  /* The 1px overlaps stop a hairline seam appearing where the
     corner piece butts up against the two filler layers. */
  -webkit-mask-size:
    var(--card-notch-w) var(--card-notch-h),
    calc(100% - var(--card-notch-w) + 1px) 100%,
    var(--card-notch-w) calc(100% - var(--card-notch-h) + 1px);
  mask-size:
    var(--card-notch-w) var(--card-notch-h),
    calc(100% - var(--card-notch-w) + 1px) 100%,
    var(--card-notch-w) calc(100% - var(--card-notch-h) + 1px);

  -webkit-mask-position: top left, top right, bottom left;
  mask-position: top left, top right, bottom left;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

.sh-card-grid__item--has-icon > * {
  position: relative;
  z-index: 1;
}

/* A box-shadow here would be shaped by the card's own (un-notched)
   border-box and bleed across the notch, so the lift replaces it. */
.sh-card-grid__item--has-icon:hover {
  box-shadow: none;
  transform: translateY(-4px);
}

/* The badge itself — same white as the card, seated in the notch
   flush to the card's top-left corner. */
.sh-card-grid__item--has-icon .sh-card-grid__icon {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  width: var(--card-icon-size);
  height: var(--card-icon-size);
  margin: 0;
  background: var(--color-surface);
}

/* The icon is inlined SVG (see card-grid.php), so `color` cascades into its currentColor fills. */
.sh-card-grid__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  margin-bottom: 1.25rem;
  border-radius: 50%;
  background-color: var(--color-bg-section);
  color: var(--icon-color, var(--color-primary));
}

/* Every icon's viewBox is cropped to its own artwork and squared off,
   so a single size here renders them all at matching optical weight —
   the source set ranges from artwork that fills its viewBox edge to
   edge (22x22) to artwork occupying barely a third of it (28x17
   inside 46x56), which is what made them look randomly sized when
   they shared one box. */
.sh-card-grid__icon svg {
  display: block;
  width: 1.75rem;
  height: 1.75rem;
}

/* The design's second tone is a lighter colour, not a transparency. */
.sh-card-grid__icon { --icon-tint: #8ec7e4; }

@supports (color: color-mix(in srgb, red 50%, white)) {
  .sh-card-grid__icon {
    --icon-tint: color-mix(in srgb, var(--icon-color, var(--color-primary)) 40%, #fff);
  }
}

.sh-card-grid__icon [data-tone-fill]   { fill: var(--icon-tint); }
.sh-card-grid__icon [data-tone-stroke] { stroke: var(--icon-tint); }

.sh-card-grid__title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--color-blue-deep);
  margin-bottom: 0.5rem;
}

.sh-card-grid__blurb {
  font-size: var(--text-base);
  line-height: 1.6;
  color: var(--color-text);
  margin-bottom: 1rem;
  flex-grow: 1;
}

.sh-card-grid__link {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-primary);
}

/* Custom card (see starfish_custom_card_from_row()) — a static <div>, not the whole-card <a> a reference card is. */
.sh-card-grid__item--custom:hover {
  border-color: var(--color-border);
  box-shadow: none;
}

.sh-card-grid__cta {
  margin-top: 0.5rem;
}

/* Button-styled CTA on a *reference* card (Card link style = Button / Outline). */
.sh-card-grid__btn {
  align-self: flex-start;
  padding: 0.625rem 1.25rem;
  font-size: var(--text-sm);
}

@media (max-width: 900px) {
  .sh-service {
    grid-template-columns: 1fr;
    /* Horizontal inset still comes from --container (88vw here), so
       only the vertical rhythm changes at this breakpoint. */
    padding: 3rem 0 4rem;
  }
  .sh-service-full {
    /* Single column — nothing sticky to keep clear of, so this is
       section separation only. */
    margin-top: 3rem;
  }
  /* Single column: the sidebar card becomes a plain heading plus the theme's listbox. */
  .sh-service__toc {
    position: static;
    max-height: none;
    overflow-y: visible;
    background: transparent;
    border: 0;
    padding: 0;
  }

  .sh-service__toc-label {
    /* Reads as a section heading here rather than the small uppercase
       sidebar label it is on desktop. */
    margin: 0 0 0.75rem;
    text-align: center;
    font-family: var(--font-display);
    font-size: var(--prose-heading, 1.625rem);
    font-weight: 700;
    text-transform: none;
    letter-spacing: 0;
    color: var(--color-heading);
  }

  .sh-service__toc-list {
    display: none;
  }

  .sh-service__toc-select {
    display: flex;
    width: 100%;
  }

  /* The listbox itself is the theme's shared control (see.sh-listbox in sections.css); only its colours change here. */
  .sh-service__toc-select .sh-listbox__toggle {
    /* Overrides the JS-measured --select-w: this control spans its
       column rather than sizing to its longest option. */
    width: 100%;
    border-color: var(--color-border);
    background: var(--color-surface);
    color: var(--color-primary);
    font-weight: 600;
  }

  /* Centres the label while leaving the chevron on the right edge,
     matching the reference. */
  .sh-service__toc-select .sh-listbox__value {
    flex: 1;
    text-align: center;
  }

  .sh-service__toc-select .sh-listbox__chevron {
    color: var(--color-heading);
  }
}

/* Card-grid column count. */
@media (max-width: 1024px) {
  .sh-card-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 640px) {
  .sh-card-grid {
    grid-template-columns: 1fr;
  }
}

/* ── Service Directory (page-service-directory.php) ──────── Reference: lifestance.com/service-directory. */
.sh-directory {
  max-width: var(--container-wide);
  margin: 0 auto;
  padding: 5rem var(--gutter);
}

.sh-directory__intro {
  text-align: center;
  margin-bottom: 2rem;
}

.sh-directory__heading {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 2.5vw, 2rem);
  font-weight: 400;
  color: var(--color-navy);
}

.sh-directory__search {
  position: relative;
  max-width: 32rem;
  margin: 0 auto 2rem;
}

.sh-directory__search-icon {
  position: absolute;
  left: 1rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-muted);
  pointer-events: none;
}

.sh-directory__input {
  width: 100%;
  padding: 0.875rem 1rem 0.875rem 2.75rem;
  border: 1px solid var(--color-border);
  border-radius: 0.75rem;
  font-size: 1rem;
  color: var(--color-heading);
  background: var(--color-surface);
}

.sh-directory__input:focus {
  outline: none;
  border-color: var(--color-primary);
}

.sh-directory__alpha {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin-bottom: 3rem;
}

.sh-directory__pill {
  min-width: 2.5rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: 0.5rem;
  background: var(--color-surface);
  color: var(--color-heading);
  font-size: 0.9375rem;
  font-weight: 600;
  cursor: pointer;
}

.sh-directory__pill:hover:not(:disabled):not(.is-active) {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.sh-directory__pill.is-active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}

.sh-directory__pill:disabled {
  color: var(--color-border);
  cursor: not-allowed;
}

.sh-directory__group {
  margin-bottom: 3rem;
}

.sh-directory__letter {
  font-family: var(--font-display);
  font-size: 1.75rem;
  font-weight: 400;
  color: var(--color-navy);
  border-bottom: 1px solid var(--color-border);
  padding-bottom: 0.75rem;
  margin-bottom: 1.5rem;
}

.sh-directory .sh-card-grid {
  grid-template-columns: repeat(2, 1fr);
}

/*.sh-card-grid__item's own `display: flex` is an author rule and
   outranks the UA stylesheet's `[hidden] { display: none }` — same
   specificity, but author always beats UA regardless of source order
   — so a card the search filter marks hidden was still rendering
   (and reserving its grid cell) without this. Groups need the same
   override for the same reason. */
.sh-directory .sh-card-grid__item[hidden],
.sh-directory__group[hidden] {
  display: none;
}

.sh-directory__empty {
  text-align: center;
  color: var(--color-muted);
  padding: 3rem 0;
}

@media (max-width: 640px) {
  .sh-directory .sh-card-grid {
    grid-template-columns: 1fr;
  }
}

/* ── Embed block ────────────────────────────────────────────── A third-party frame (video, form, scheduler, map) placed as a content block. */
.sh-embed {
  position: relative;
  width: 100%;
  overflow: hidden;
  border-radius: var(--radius-lg, 1rem);
  /* A tint behind the frame, so a slow-loading embed reads as a
     space reserved for something rather than a hole in the page.
     --block-bg is set (as an inline custom property, inherited down
     from.sh-content-block--bg) only when an editor actually chose a
     Section Background for this block — falls back to the same
     neutral tint as before when they haven't, so a plain embed block
     is unaffected. Matching it here is only the placeholder colour,
     not the iframe's own background once it loads — that is a
     separate cross-origin document this CSS cannot reach. */
  background: var(--block-bg, var(--color-bg-section));
}

/* Auto height: no ratio at all. */
.sh-embed--auto { aspect-ratio: auto; }

.sh-embed--16-9 { aspect-ratio: 16 / 9; }
.sh-embed--4-3  { aspect-ratio: 4 / 3; }
.sh-embed--1-1  { aspect-ratio: 1 / 1; }

/* Fixed height comes inline, per block — no aspect-ratio to fight
   with it. Forms are the case: as tall as their own content, with no
   shape that survives being scaled. */
.sh-embed--fixed { aspect-ratio: auto; }

.sh-embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* Removed outright by embed-autoheight.js once the iframe's own 'load' event fires — not toggled with a class, so there is nothing left in the DOM (or the accessibility tree) once the real content has arrived. */
.sh-embed__loading {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  background: inherit;
  pointer-events: none;
}

/* The spinner variant centres a single small element; the skeleton
   variant (below) fills the box edge to edge instead, so each gets
   its own alignment rather than one shared rule trying to suit both. */
.sh-embed__loading--spinner {
  align-items: center;
  justify-content: center;
}

.sh-embed__spinner {
  width: 2.75rem;
  height: 2.75rem;
  border: 4px dashed color-mix(in srgb, var(--color-primary) 35%, white);
  border-top: 4px solid var(--color-primary);
  border-radius: 50%;
  animation: sh-embed-spin 1s linear infinite;
}

@keyframes sh-embed-spin {
  to { transform: rotate(360deg); }
}

/* ── Form skeleton ───────────────────────────────────────────── a GENERIC form shape (label/input rows, a button bottom-right) rather than a copy of any one embedded form's real fields — see the comment in content-blocks.php on why. */
.sh-embed__skeleton {
  width: 100%;
  max-width: 34rem;
  margin: 2.5rem auto;
  padding: 0 var(--gutter);
}

.sh-embed__skel-row {
  display: flex;
  gap: 1.25rem;
  margin-bottom: 1.5rem;
}

.sh-embed__skel-row--end {
  justify-content: flex-end;
  margin-bottom: 0;
}

.sh-embed__skel-field {
  flex: 1;
  display: block;
}

.sh-embed__skel-label,
.sh-embed__skel-input,
.sh-embed__skel-button {
  display: block;
  border-radius: var(--radius-md, 0.5rem);
  /* One shimmer sweep, shared by every bar via background-position
     rather than each bar running its own independent animation —
     keeps every piece of the skeleton in visual sync, the way a real
     shimmer effect reads as one coherent surface rather than several
     unrelated blocks each doing their own thing. */
  background: linear-gradient(
    100deg,
    color-mix(in srgb, var(--color-border, #e2e2e2) 70%, transparent) 30%,
    color-mix(in srgb, var(--color-border, #e2e2e2) 30%, transparent) 50%,
    color-mix(in srgb, var(--color-border, #e2e2e2) 70%, transparent) 70%
  );
  background-size: 200% 100%;
  animation: sh-embed-shimmer 1.6s ease-in-out infinite;
}

.sh-embed__skel-label {
  width: 45%;
  height: 0.625rem;
  margin-bottom: 0.5rem;
}

.sh-embed__skel-input {
  height: 2.25rem;
}

.sh-embed__skel-button {
  width: 6rem;
  height: 2.25rem;
  border-radius: var(--radius-pill, 999px);
}

@keyframes sh-embed-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .sh-embed__spinner,
  .sh-embed__skel-label,
  .sh-embed__skel-input,
  .sh-embed__skel-button {
    animation: none;
  }
}

/* Must follow the rule above, not precede it: both are one class plus one element (0,1,1), so specificity cannot separate them and source order is the only thing that decides. */
.sh-embed--auto iframe {
  position: static;
  height: auto;
  /* The floor until the embed reports its real height; JS then sets an
     explicit height, which wins over this. Without JS, or with an
     embed that reports nothing, the frame still fills the starting
     height rather than collapsing to the HTML default 150px. */
  min-height: inherit;
}

/* A fixed-height embed on a phone: a 700px form on a 640px screen
   leaves nothing else visible. Capped to most of the viewport and
   allowed to scroll internally instead. */
@media (max-width: 768px) {
  .sh-embed--fixed { max-height: 80vh; }
}

/* MOTION — PAGE LOAD, HOVER & LOADING STATES ------------------------------------------------------------ Extends the reveal primitive above. */

/* ── 1. Hero: staggered rise on load ─────────────────────────
   An animation, not a transition, so it runs to completion on its
   own — there is no JS in this path at all, and no way for a hero to
   be left stranded mid-fade. 12px of travel, 50ms apart. */
@keyframes sh-hero-rise {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: none; }
}

.sh-motion .sh-hero__breadcrumbs,
.sh-motion .sh-hero__headline,
.sh-motion .sh-hero__subtext,
.sh-motion .sh-hero__ctas,
.sh-motion .sh-hero__meta,
.sh-motion .sh-hero-note {
  animation: sh-hero-rise 0.6s cubic-bezier(0.4, 0, 0.2, 1) both;
}

/* Last in, after the buttons it describes. */
.sh-motion .sh-hero-note { animation-delay: 360ms; }

.sh-motion .sh-hero__breadcrumbs { animation-delay: 0ms; }
.sh-motion .sh-hero__headline    { animation-delay: 90ms; }
.sh-motion .sh-hero__subtext     { animation-delay: 180ms; }
.sh-motion .sh-hero__ctas        { animation-delay: 270ms; }
.sh-motion .sh-hero__meta        { animation-delay: 360ms; }

/* The side hero (About, Services, Who We Help) is a different layout
   with its own class names, so it needs naming separately — only its
   breadcrumbs carry the shared.sh-hero__breadcrumbs class and were
   already animating, which left the headline below them appearing
   instantly while the crumb above it rose. The media column is
   deliberately left alone: it is the full-bleed background, and
   fading the whole panel in reads as the page still loading. */
.sh-motion .sh-hero-side__headline,
.sh-motion .sh-hero-side__subtext,
.sh-motion .sh-hero-side__action {
  animation: sh-hero-rise 0.6s cubic-bezier(0.4, 0, 0.2, 1) both;
}

.sh-motion .sh-hero-side__headline { animation-delay: 90ms; }
.sh-motion .sh-hero-side__subtext  { animation-delay: 180ms; }
.sh-motion .sh-hero-side__action   { animation-delay: 270ms; }

/* The stacked hero (Contact, Intake, Refer a Patient, Service
   Directory, and About's default) had NO entrance animation at all —
   its headline/subtext/CTA row use their own __-namespaced classes,
   distinct from.sh-hero__* (cover) and.sh-hero-side__* (side), so
   neither existing rule ever matched them. Breadcrumbs are already
   covered: stacked reuses the shared.sh-hero__breadcrumbs class
   above. The media strip/cards are left alone, same reasoning as
   side's photo column — it is content, not chrome, and fading the
   whole panel in reads as the page still loading. */
.sh-motion .sh-hero-stacked__headline,
.sh-motion .sh-hero-stacked__subtext,
.sh-motion .sh-hero-ctas {
  animation: sh-hero-rise 0.6s cubic-bezier(0.4, 0, 0.2, 1) both;
}

.sh-motion .sh-hero-stacked__headline { animation-delay: 90ms; }
.sh-motion .sh-hero-stacked__subtext  { animation-delay: 180ms; }
.sh-motion .sh-hero-ctas              { animation-delay: 270ms; }

/* Individual location page: the top block (breadcrumb → address →
   title → contacts → map) is above the fold, so it uses the same
   on-load rise every hero does rather than a scroll reveal — nothing
   here is ever below the viewport on first paint. */
.sh-motion .sh-loc-detail__crumbs,
.sh-motion .sh-loc-detail__address,
.sh-motion .sh-loc-detail__title,
.sh-motion .sh-loc-detail__contacts,
.sh-motion .sh-loc-detail__map {
  animation: sh-hero-rise 0.6s cubic-bezier(0.4, 0, 0.2, 1) both;
}

.sh-motion .sh-loc-detail__crumbs    { animation-delay: 0ms; }
.sh-motion .sh-loc-detail__address   { animation-delay: 70ms; }
.sh-motion .sh-loc-detail__title     { animation-delay: 130ms; }
.sh-motion .sh-loc-detail__contacts  { animation-delay: 200ms; }
.sh-motion .sh-loc-detail__map       { animation-delay: 260ms; }

/* ── 2. Feature cards: alternating entry ─────────────────────
   Odd cards come from the left, even from the right, replacing the
   straight vertical rise for these grids only. Travel stays small
   (12px) so a four-across row reads as one movement rather than a
   scatter. Overrides the primitive's translateY, so it must come
   after it — and stays above `.is-visible`, which resets both. */
.sh-motion .page-home .sh-card-grid__item:nth-child(odd),
.sh-motion .page-home .sh-step-card:nth-child(odd),
.sh-motion .page-home .sh-cat-card:nth-child(odd),
.sh-motion .page-home .sh-why__col:nth-child(odd) {
  --sh-enter-x: -24px;
  --sh-enter-y: 0px;
}

.sh-motion .page-home .sh-card-grid__item:nth-child(even),
.sh-motion .page-home .sh-step-card:nth-child(even),
.sh-motion .page-home .sh-cat-card:nth-child(even),
.sh-motion .page-home .sh-why__col:nth-child(even) {
  --sh-enter-x: 24px;
  --sh-enter-y: 0px;
}

/* ── 3. Cards: hover elevation ───────────────────────────────
   4px lift with the resting shadow expanding underneath. Hover-capable
   pointers only — on touch these fire on tap and stick. */
/*.sh-step-card is deliberately absent: "How it works" is a numbered
   sequence, not a set of cards you can act on, so lifting it on hover
   would promise an interaction that isn't there. */
.sh-card-grid__item,
.sh-locations-card,
.sh-audience-card,
.sh-team-card {
  transition:
    transform 0.2s ease-out,
    box-shadow 0.2s ease-out;
}

/* Once revealed, the card hands its `transition` back over to the hover timings, so box-shadow (which the reveal rule does not list) eases rather than snapping. */
.sh-motion .sh-card-grid__item.sh-motion-done,
.sh-motion .sh-locations-card.sh-motion-done,
.sh-motion .sh-audience-card.sh-motion-done,
.sh-motion .sh-team-card.sh-motion-done,
.sh-motion .sh-cd-card.sh-motion-done,
.sh-motion .sh-loc-services__item.sh-motion-done,
.sh-motion .sh-accept-card.sh-motion-done {
  transition:
    transform 0.2s ease-out,
    box-shadow 0.2s ease-out;
}

@media (hover: hover) and (pointer: fine) {
  /* :not(--has-icon) matters. */
  .sh-card-grid__item:not(.sh-card-grid__item--has-icon):hover,
  .sh-locations-card:hover,
  .sh-audience-card:hover,
  .sh-team-card:hover,
  .sh-cd-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 0.75rem 1.75rem rgba(16, 68, 95, 0.13);
  }

  /* Already lifted 3px before this system existed — brought in line
     with the 4px the rest of the cards use, and given the matching
     shadow it was missing. */
  .sh-ic-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 0.75rem 1.75rem rgba(16, 68, 95, 0.13);
  }
}

/* ── 4. Buttons & CTAs ───────────────────────────────────────
   The pill buttons already animated their arrow; this adds the scale,
   shadow and background shift they were missing. background-color is
   named explicitly rather than `all` so the transform below keeps its
   own faster timing. */
/* The intake banner's secondary and phone CTAs are not.sh-btn — they
   are their own pill classes — so they need naming here or they keep
   the colour-only hover they have always had while every other CTA
   gained scale and shadow. */
.sh-btn,
.sh-banner__intake-secondary,
.sh-banner__intake-outline,
.sh-loc-card__cta,
.sh-loc-card__directions,
/* Arrow-less CTAs were never named here, so they had a colour swap on
   hover and nothing else — no lift, no shadow, no press. The arrow is
   decoration; it should not decide whether a button reacts. */
.sh-cta-note {
  transition:
    background-color 0.2s ease-out,
    color 0.2s ease-out,
    border-color 0.2s ease-out,
    box-shadow 0.2s ease-out,
    transform 0.2s ease-out;
}

@media (hover: hover) and (pointer: fine) {
  .sh-btn:hover,
  .sh-banner__intake-secondary:hover,
  .sh-banner__intake-outline:hover,
  .sh-loc-card__cta:hover,
  .sh-cta-note:hover {
    transform: scale(1.02);
    box-shadow: 0 0.5rem 1.25rem rgba(16, 68, 95, 0.18);
  }

  /* Directions is a text link, not a pill — scaling text reads as a
     glitch, not a lift, so it gets the colour transition above only. */
  .sh-loc-card__directions:hover {
    transform: translateX(2px);
  }

  .sh-cta-link:hover .sh-btn__icon,
  .sh-cta-link:hover svg { transform: translateX(2px); }
}

.sh-cta-link svg { transition: transform 0.2s ease-out; }

/* Press feedback, on every pointer type — this is the one state that
   must also work on touch, and it is deliberately quicker than the
   hover so the button feels like it answers instantly. */
.sh-btn:active,
.sh-banner__intake-secondary:active,
.sh-banner__intake-outline:active {
  transform: scale(0.98);
  transition-duration: 0.08s;
}

/* Loading states for asynchronously loaded media. */
.sh-media-loading {
  position: relative;
  background: color-mix(in srgb, var(--color-border, #e2e2e2) 45%, transparent);
  background-image: linear-gradient(
    100deg,
    color-mix(in srgb, var(--color-border, #e2e2e2) 70%, transparent) 30%,
    color-mix(in srgb, var(--color-border, #e2e2e2) 30%, transparent) 50%,
    color-mix(in srgb, var(--color-border, #e2e2e2) 70%, transparent) 70%
  );
  background-size: 200% 100%;
  animation: sh-embed-shimmer 1.6s ease-in-out infinite;
}

.sh-media-loading img {
  opacity: 0;
  transition: opacity 0.25s ease-out;
}

.sh-media-ready img { opacity: 1; }

/* ── Reduced motion: neutralise everything above ─────────────
   The.sh-motion opt-in already prevents most of this, but these are
   unscoped hover/press states, so they need their own guard. */
@media (prefers-reduced-motion: reduce) {
  .sh-motion .sh-hero__breadcrumbs,
  .sh-motion .sh-hero__headline,
  .sh-motion .sh-hero__subtext,
  .sh-motion .sh-hero__ctas,
  .sh-motion .sh-hero__meta,
  .sh-motion .sh-hero-side__headline,
  .sh-motion .sh-hero-side__subtext,
  .sh-motion .sh-hero-side__action,
  .sh-motion .sh-hero-stacked__headline,
  .sh-motion .sh-hero-stacked__subtext,
  .sh-motion .sh-hero-ctas,
  .sh-motion .sh-hero-note {
    animation: none;
  }

  .sh-motion .page-home .sh-card-grid__item,
  .sh-motion .page-home .sh-step-card,
  .sh-motion .page-home .sh-cat-card,
  .sh-motion .page-home .sh-why__col {
    --sh-enter-x: 0px;
    --sh-enter-y: 0px;
  }

  .sh-card-grid__item,
  .sh-locations-card,
  .sh-audience-card,
  .sh-team-card,
  .sh-cd-card,
  .sh-btn,
  .sh-banner__intake-secondary,
  .sh-banner__intake-outline,
  .sh-cta-link svg {
    transition: none;
  }

  .sh-card-grid__item:hover,
  .sh-locations-card:hover,
  .sh-audience-card:hover,
  .sh-team-card:hover,
  .sh-cd-card:hover,
  .sh-ic-card:hover,
  .sh-btn:hover,
  .sh-btn:active,
  .sh-banner__intake-secondary:hover,
  .sh-banner__intake-secondary:active,
  .sh-banner__intake-outline:hover,
  .sh-banner__intake-outline:active,
  .sh-loc-card__cta:hover,
  .sh-loc-card__directions:hover,
  .sh-loc-detail__directions:hover,
  .sh-cta-note,
  .sh-cta-note:hover,
  .sh-cta-note:active {
    transform: none;
    box-shadow: none;
  }

  .sh-media-loading { animation: none; }
  .sh-media-loading img { opacity: 1; transition: none; }
}

/* ── Our Story cards: interactive hover ──────────────────────
   These are articles rather than links, so the treatment stays
   descriptive: the card lifts and the icon disc grows a little inside
   its tinted ring, which reads as "there is something here" without
   promising a click target the way a full card-link would. */
.sh-story-card {
  transition:
    transform 0.2s ease-out,
    box-shadow 0.2s ease-out;
}

.sh-story-card__icon,
.sh-story-card__disc {
  transition: transform 0.25s ease-out, background-color 0.25s ease-out;
}

@media (hover: hover) and (pointer: fine) {
  .sh-story-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 0.75rem 1.75rem rgba(16, 68, 95, 0.13);
  }

  .sh-story-card:hover .sh-story-card__disc { transform: scale(1.08); }
  .sh-story-card:hover .sh-story-card__icon { transform: scale(1.03); }
}

/* Hand `transition` over once the reveal has finished — same reason
   as the other revealed cards above. */
.sh-motion .sh-story-card.sh-motion-done {
  transition:
    transform 0.2s ease-out,
    box-shadow 0.2s ease-out;
}

/* ── Buttons on dark grounds ───────────────────────────────── The shared hover shadow is navy at 18%, which is invisible against the navy side-hero and the dark banners these two variants live on — the button scaled but looked like it did nothing. */
@media (hover: hover) and (pointer: fine) {
  .sh-btn--outline-contrast:hover,
  .sh-btn--pill-white:hover {
    box-shadow: 0 0.5rem 1.25rem rgba(0, 0, 0, 0.28), 0 0 0 1px rgba(255, 255, 255, 0.22);
  }
}

@media (prefers-reduced-motion: reduce) {
  .sh-story-card,
  .sh-story-card__icon,
  .sh-story-card__disc { transition: none; }

  .sh-story-card:hover,
  .sh-story-card:hover .sh-story-card__disc,
  .sh-story-card:hover .sh-story-card__icon {
    transform: none;
    box-shadow: none;
  }

  .sh-btn--outline-contrast:hover,
  .sh-btn--pill-white:hover { box-shadow: none; }
}

/* ── Vision & Mission: motion sized to the surface ─────────── These cards are 42rem tall, and the shared 24px rise is invisible on something that big — the section read as having no transition at all. */
.sh-motion .sh-vm__card {
  --sh-enter-y: 0.75rem;
}

/* Photo eases out of a slight over-scale as the card arrives, which
   is the part that actually reads on a surface this size. */
.sh-motion .sh-vm__card::before {
  transform: scale(1.06);
  transition: transform 0.7s cubic-bezier(0.4, 0, 0.2, 1);
}

.sh-motion .sh-vm__card.is-visible::before { transform: none; }

/* The caption itself is deliberately NOT animated: it simply appears
   with the card. It had its own delayed slide-up, which drew the eye
   to the copy moving rather than to the copy. The photo easing out of
   its over-scale is the section's motion; the text just arrives. */

/* Hover: the card lifts like every other card on the site, and the
   caption deepens so the copy gains contrast as it comes forward. */
.sh-vm__card { transition: transform 0.2s ease-out, box-shadow 0.2s ease-out; }
.sh-vm__panel { transition: background-color 0.25s ease-out; }

@media (hover: hover) and (pointer: fine) {
  .sh-vm__card:hover {
    transform: translateY(-4px);
    box-shadow: 0 1rem 2.25rem rgba(16, 68, 95, 0.22);
  }
  .sh-vm__card:hover .sh-vm__panel { background: rgba(0, 0, 0, 0.78); }

  /* Photo-card hover the section never had: the image pushes in behind a caption that stays put, because only the photo layer moves. */
  .sh-motion .sh-vm__card.is-visible:hover::before,
  .sh-vm__card:hover::before { transform: scale(1.04); }
}

.sh-motion .sh-vm__card.sh-motion-done {
  transition: transform 0.2s ease-out, box-shadow 0.2s ease-out;
}

@media (prefers-reduced-motion: reduce) {
  .sh-motion .sh-vm__card { --sh-enter-y: 0px; }

  .sh-motion .sh-vm__card::before,
  .sh-motion .sh-vm__card.is-visible::before,
  .sh-motion .sh-vm__card.is-visible:hover::before,
  .sh-vm__card:hover::before {
    transform: none;
    transition: none;
  }
  .sh-vm__card,
  .sh-vm__panel { transition: none; }
  .sh-vm__card:hover { transform: none; box-shadow: none; }
}

/* ── Our Story: two-beat reveal ────────────────────────────── The card arrives first, then its icon settles into the disc a beat later. */
.sh-motion .sh-story-card .sh-story-card__disc {
  opacity: 0;
  transform: scale(0.72);
  transition:
    opacity 0.4s cubic-bezier(0.4, 0, 0.2, 1),
    transform 0.45s cubic-bezier(0.34, 1.4, 0.64, 1);
  transition-delay: 160ms;
}

.sh-motion .sh-story-card.is-visible .sh-story-card__disc {
  opacity: 1;
  transform: none;
}

/* The tinted ring behind it opens up at the same time. */
.sh-motion .sh-story-card .sh-story-card__icon {
  transform: scale(0.94);
  transition: transform 0.45s cubic-bezier(0.4, 0, 0.2, 1);
  transition-delay: 120ms;
}

.sh-motion .sh-story-card.is-visible .sh-story-card__icon { transform: none; }

/* Hover keeps ownership once the reveal is finished, so the disc still
   grows under the pointer rather than being frozen by the rule above. */
.sh-motion .sh-story-card.sh-motion-done .sh-story-card__disc,
.sh-motion .sh-story-card.sh-motion-done .sh-story-card__icon {
  transition: transform 0.25s ease-out, background-color 0.25s ease-out;
  transition-delay: 0s;
}

@media (prefers-reduced-motion: reduce) {
  .sh-motion .sh-story-card .sh-story-card__disc,
  .sh-motion .sh-story-card .sh-story-card__icon,
  .sh-motion .sh-story-card.is-visible .sh-story-card__disc,
  .sh-motion .sh-story-card.is-visible .sh-story-card__icon {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ── Insurance & Payment: white page ground ──────────────────
   The site default (--color-bg) is a faint grey that most sections
   sit transparently on top of. This page's own sections are white or
   near-white, so that tint only showed as seams between them. */
body.page-insurance { background-color: #ffffff; }
body.page-refer { background-color: #ffffff; }
