/*
 * components.css — generated by wordpress/tools/extract-css.mjs
 *
 * Lifted verbatim from the Astro components listed below, with :global()
 * wrappers unwrapped and dead rules dropped. DO NOT hand-edit: rerun the
 * extractor instead, or the theme and the Astro source drift apart.
 */

/* ==========================================================
   SectionHead.astro
   ========================================================== */

  .sechead {
    margin: 0 0 var(--s-7);
    max-width: 30ch;
  }

  .sechead--tight {
    margin-bottom: var(--s-5);
  }

/* ==========================================================
   SiteHeader.astro
   ========================================================== */

  .nav {
    position: sticky;
    top: 0;
    z-index: var(--z-nav);
    background: var(--c-black);
    color: var(--c-on-dark);
  }

  .nav__inner {
    display: flex;
    align-items: center;
    gap: var(--s-5);
    width: 100%;
    max-width: var(--container-wide);
    margin-inline: auto;
    padding: var(--s-4) var(--gutter);
  }

  .nav__logo {
    flex: none;
    line-height: 0;
  }

  .nav__logo img {
    width: clamp(9rem, 14vw, 13.75rem);
    height: auto;
  }

  /* ---------- burger ---------- */

  .nav__burger {
    order: 3;
    margin-left: auto;
    display: grid;
    gap: 5px;
    width: 44px;
    height: 44px;
    padding: 11px 9px;
    background: none;
    border: 0;
    cursor: pointer;
  }

  .nav__burger span {
    display: block;
    height: 1.5px;
    background: var(--c-on-dark);
    transition: transform var(--dur-base) var(--ease-out), opacity var(--dur-fast) linear;
  }

  .nav[data-open] .nav__burger span:nth-child(1) {
    transform: translateY(6.5px) rotate(45deg);
  }
  .nav[data-open] .nav__burger span:nth-child(2) {
    opacity: 0;
  }
  .nav[data-open] .nav__burger span:nth-child(3) {
    transform: translateY(-6.5px) rotate(-45deg);
  }

  /* ---------- mobile panel ---------- */

  .nav__menu {
    display: none;
    order: 4;
    flex-basis: 100%;
    padding-block: var(--s-5) var(--s-4);
  }

  .nav[data-open] .nav__menu {
    display: block;
  }

  .nav__list {
    list-style: none;
    margin: 0;
    padding: 0;
  }

  .nav__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
  }

  .nav__link,
  .nav__sublink {
    display: block;
    padding: var(--s-3) 0;
    font-family: var(--font-display);
    font-size: var(--t-small);
    /* Nav items are UI labels, so 500 per the role table. At 300 they sat three
       weights apart from the pill CTA beside them, which was the most visible
       weight clash on the page. */
    font-weight: var(--fw-medium);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--c-on-dark);
    transition: color var(--dur-fast) linear;
  }

  .nav__link:hover,
  .nav__sublink:hover,
  .nav__link.is-active {
    color: var(--c-taupe);
  }

  .nav__caret {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    background: none;
    border: 0;
    color: inherit;
    cursor: pointer;
  }

  .nav__caret svg {
    width: 10px;
    transition: transform var(--dur-base) var(--ease-out);
  }

  [data-sub][data-open] .nav__caret svg {
    transform: rotate(180deg);
  }

  .nav__sub {
    display: none;
    list-style: none;
    margin: 0 0 var(--s-3);
    padding-left: var(--s-4);
    border-left: 1px solid rgba(237, 232, 228, 0.25);
  }

  [data-sub][data-open] .nav__sub {
    display: block;
  }

  .nav__sub .nav__sublink {
    padding: var(--s-2) 0;
    font-size: var(--t-micro);
    letter-spacing: 0.08em;
    color: var(--c-on-dark-muted);
  }

  .nav__cta {
    margin-top: var(--s-4);
    width: 100%;
  }

  /* ---------- desktop ----------
     Breakpoint is 1140px, not 1024px. Six nav items plus the logo plus the
     pill CTA measured 1072px of content, so switching to the horizontal nav at
     1024px pushed the CTA off-screen on every page. Below 1140px the burger is
     the correct layout. */

  @media (min-width: 1140px) {
    .nav__burger {
      display: none;
    }

    .nav__menu {
      display: flex !important;
      order: 2;
      align-items: center;
      gap: var(--s-4);
      flex-basis: auto;
      margin-left: auto;
      padding-block: 0;
    }

    .nav__list {
      display: flex;
      align-items: center;
      gap: var(--s-1);
    }

    .nav__item {
      position: relative;
    }

    .nav__link {
      padding: var(--s-2) var(--s-3);
      font-size: var(--t-micro);
    }

    .nav__row {
      gap: 0;
    }

    .nav__caret {
      width: 20px;
      height: 20px;
      margin-left: -6px;
    }

    /* Submenu is a floating panel on desktop, opened by hover or focus. */
    .nav__sub {
      position: absolute;
      top: 100%;
      left: 0;
      display: block;
      min-width: 15rem;
      margin: 0;
      padding: var(--s-3) 0;
      background: var(--c-black);
      border-left: 0;
      box-shadow: var(--shadow-lg);
      opacity: 0;
      visibility: hidden;
      transform: translateY(-6px);
      transition:
        opacity var(--dur-base) var(--ease-out),
        transform var(--dur-base) var(--ease-out),
        visibility var(--dur-base) linear;
    }

    .nav__item--has-sub:hover .nav__sub,
    .nav__item--has-sub:focus-within .nav__sub,
    [data-sub][data-open] .nav__sub {
      opacity: 1;
      visibility: visible;
      transform: none;
    }

    .nav__sub .nav__sublink {
      padding: var(--s-2) var(--s-5);
    }

    .nav__cta {
      margin-top: 0;
      width: auto;
      flex: none;
    }
  }

/* ==========================================================
   SiteFooter.astro
   ========================================================== */

  .foot {
    background: var(--c-black);
    color: var(--c-on-dark-muted);
    padding-block: var(--s-9) var(--s-6);
    font-size: var(--t-small);
  }

  .foot__top {
    display: grid;
    gap: var(--s-8);
  }

  @media (min-width: 900px) {
    .foot__top {
      grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr);
      gap: var(--s-9);
    }
  }

  .foot__wordmark {
    margin: 0 0 var(--s-4);
    font-family: var(--font-display);
    font-size: var(--t-h3);
    font-weight: var(--fw-light);
    letter-spacing: var(--ls-display);
    text-transform: uppercase;
    color: var(--c-on-dark);
  }

  .foot__promise {
    max-width: 34ch;
    margin: 0 0 var(--s-5);
    line-height: var(--lh-body);
  }

  .foot__contact {
    list-style: none;
    margin: var(--s-5) 0 0;
    padding: 0;
    display: grid;
    gap: var(--s-2);
  }

  .foot__contact a {
    color: var(--c-on-dark);
    text-decoration: none;
  }

  .foot__contact a:hover {
    text-decoration: underline;
  }

  .foot__cols {
    display: grid;
    gap: var(--s-7);
  }

  @media (min-width: 560px) {
    .foot__cols {
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: var(--s-5);
    }
  }

  .foot__head {
    margin: 0 0 var(--s-4);
    font-family: var(--font-display);
    font-size: var(--t-micro);
    font-weight: var(--fw-medium);
    letter-spacing: var(--ls-label);
    text-transform: uppercase;
    color: var(--c-on-dark);
  }

  .foot__col ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--s-2);
  }

  .foot__col a {
    color: var(--c-on-dark-muted);
    text-decoration: none;
    transition: color var(--dur-fast) linear;
  }

  .foot__col a:hover {
    color: var(--c-on-dark);
    text-decoration: underline;
  }

  .foot__bottom {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-4);
    justify-content: space-between;
    align-items: center;
    margin-top: var(--s-8);
    padding-top: var(--s-5);
    border-top: 1px solid rgba(237, 232, 228, 0.18);
    font-size: var(--t-micro);
  }

  .foot__bottom p {
    margin: 0;
  }

  /*
   * The build credit, on its own line under everything else.
   *
   * flex-basis 100% rather than a fourth item in the row: .foot__bottom is a
   * space-between flex row holding the copyright and the legal links, and a
   * third item there would have squeezed both and pulled the legal menu off the
   * right edge on a narrow screen. This drops below them instead, which is also
   * where Doug asked for it — "the last little bit at the bottom".
   *
   * A step quieter than the line above it. It is a credit, not a claim on the
   * client's footer.
   */
  .foot__credit {
    flex: 1 0 100%;
    margin: 0;
    padding-top: var(--s-3);
    color: var(--c-on-dark-muted);
    opacity: 0.75;
  }

  .foot__credit a {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }

  .foot__credit a:hover {
    color: var(--c-on-dark);
  }

  .foot__legal {
    display: flex;
    gap: var(--s-5);
    list-style: none;
    margin: 0;
    padding: 0;
  }

  .foot__legal a {
    color: var(--c-on-dark-muted);
  }

/* ==========================================================
   Breadcrumbs.astro
   ========================================================== */

  .crumbs{
    padding-block: var(--s-4);
    background: var(--c-taupe);
    font-size: var(--t-micro);
  }

  .crumbs ol{
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-2);
    list-style: none;
    margin: 0;
    padding: 0;
  }

  .crumbs li{
    display: flex;
    align-items: center;
    gap: var(--s-2);
    color: var(--c-ink-soft);
  }

  .crumbs li + li::before{
    content: "/";
    color: var(--c-taupe-deeper);
  }

  .crumbs a{
    color: var(--c-ink-soft);
    text-decoration: none;
  }

  .crumbs a:hover{
    text-decoration: underline;
  }

  span[aria-current]{
    color: var(--c-ink);
  }

/* ==========================================================
   PageHero.astro
   ========================================================== */

  .phero {
    background: var(--c-taupe);
    padding-block: var(--s-7) var(--s-8);
  }

  .phero__grid {
    display: grid;
    gap: var(--s-5);
  }

  .phero__panel {
    background: var(--c-cream);
    padding: var(--s-7) var(--s-6);
  }

  .phero--text .phero__panel {
    max-width: 60rem;
  }

  .phero__title {
    margin-bottom: var(--s-5);
  }

  .phero__lead {
    max-width: 52ch;
    margin: 0;
    font-size: var(--t-lead);
    color: var(--c-ink-soft);
    text-wrap: pretty;
  }

  .phero__actions {
    margin-top: var(--s-6);
  }

  .phero__media img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
  }

  @media (min-width: 900px) {
    .phero__grid {
      grid-template-columns: minmax(0, 1fr) minmax(0, 0.95fr);
      align-items: center;
      gap: 0;
    }

    .phero__panel {
      position: relative;
      z-index: var(--z-raised);
      margin-right: calc(var(--s-7) * -1);
      padding: var(--s-8) var(--s-8);
    }

    .phero--text .phero__grid {
      grid-template-columns: minmax(0, 1fr);
    }

    .phero--text .phero__panel {
      margin-right: 0;
    }

    .phero__media img {
      aspect-ratio: 3 / 4;
      max-height: 34rem;
    }
  }

/* ==========================================================
   ServiceGrid.astro
   ========================================================== */


  .sg__grid {
    display: grid;
    gap: var(--s-6);
    list-style: none;
    margin: 0;
    padding: 0;
  }

  @media (min-width: 680px) {
    .sg__grid {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }
  }

  @media (min-width: 1100px) {
    /* Uneven tracks and a vertical stagger. Four identical columns with four
       identical portrait images is the most template-looking arrangement on the
       page; offsetting the even cards breaks the shared baseline and lets the eye
       travel rather than scan a row. */
    .sg__grid {
      grid-template-columns: 1.14fr 1fr 1fr 1.08fr;
      gap: var(--s-5);
      align-items: start;
    }

    .sg__card:nth-child(2n) {
      margin-top: var(--s-8);
    }
  }

  .sg__link {
    display: flex;
    flex-direction: column;
    gap: var(--s-3);
    height: 100%;
    text-decoration: none;
  }

  .sg__media {
    overflow: hidden;
    margin-bottom: var(--s-2);
  }

  /* Portrait crop, because that is what the source photography is. */
  .sg__media img {
    width: 100%;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    transition: transform var(--dur-slow) var(--ease-out);
  }

  .sg__link:hover .sg__media img {
    transform: scale(1.04);
  }

  /* Titles run one or two lines ("Move Concierge" vs "Organizing &
     Decluttering"). Reserving two lines keeps the summaries on a shared
     baseline across the row instead of stepping up and down. */
  .sg__title {
    color: var(--c-ink);
    min-height: 2.5em;
  }

  @media (max-width: 679px) {
    .sg__title {
      min-height: 0;
    }
  }

  .sg__summary {
    flex: 1;
    margin: 0;
    font-size: var(--t-small);
    color: var(--c-ink-soft);
    text-wrap: pretty;
  }

  .sg__cta {
    margin-top: var(--s-2);
  }

/* ==========================================================
   ServiceAreaPanel.astro
   ========================================================== */

  .sap {
    position: relative;
    isolation: isolate;
    background: var(--c-brown-deep);
    color: var(--c-on-dark-muted);
    overflow: hidden;
  }

  /* ---------- map ---------- */

  .sap__map {
    margin: 0;
  }

  .sap__map img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
  }

  .sap__credit {
    padding: var(--s-3) var(--gutter);
    font-size: var(--t-micro);
    color: var(--c-ink-muted);
    background: var(--c-cream);
  }

  .sap__credit a {
    color: inherit;
  }

  /* ---------- copy ---------- */

  .sap__inner {
    position: relative;
    z-index: 2;
    width: 100%;
    max-width: var(--container-wide);
    margin-inline: auto;
    padding-inline: var(--gutter);
  }

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

  .sap__panel .sechead {
    color: var(--c-on-dark);
  }

  .sap__lead {
    max-width: 46ch;
    margin: 0;
    font-size: var(--t-lead);
    color: var(--c-on-dark-muted);
    text-wrap: pretty;
  }

  .sap__rule {
    display: block;
    width: 56px;
    height: 2px;
    margin: var(--s-6) 0;
    background: var(--c-taupe);
  }

  /* ---------- county lists ---------- */

  .sap__counties {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s-5) var(--s-4);
  }

  @media (min-width: 560px) {
    .sap__counties {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }
  }

  .sap__countyName {
    margin: 0 0 var(--s-4);
    font-family: var(--font-display);
    font-weight: var(--fw-medium);
    font-size: var(--t-micro);
    letter-spacing: var(--ls-label);
    text-transform: uppercase;
    color: var(--c-taupe);
  }

  .sap__county ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--s-3);
  }

  .sap__county a {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    font-size: var(--t-small);
    text-decoration: none;
    color: var(--c-on-dark);
    transition: color var(--dur-fast) linear;
  }

  .sap__county a svg {
    flex: none;
    width: 15px;
    height: 15px;
    /* Navy would be invisible on black; the check rides on the warm accent. */
    color: var(--c-taupe);
  }

  .sap__county a:hover {
    color: var(--c-taupe);
    text-decoration: underline;
  }

  .sap__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-4) var(--s-5);
    margin-top: var(--s-7);
  }

  .sap__call {
    font-family: var(--font-display);
    font-weight: var(--fw-medium);
    font-size: var(--t-micro);
    letter-spacing: var(--ls-button);
    text-transform: uppercase;
    text-decoration: none;
    color: var(--c-on-dark-muted);
  }

  .sap__call:hover {
    color: var(--c-on-dark);
    text-decoration: underline;
  }

  /* ---------- desktop: panel left, map bleeding off the right ---------- */

  @media (min-width: 900px) {
    .sap__map {
      position: absolute;
      inset: 0 0 0 20%;
      z-index: 0;
    }

    .sap__map img {
      height: 100%;
      aspect-ratio: auto;
      object-position: 40% center;
    }

    /* Solid to 44%, then a long fade out to the right edge. Measured off the
       reference, which fades from 46% all the way to 99%. A short fade reads as a
       seam rather than a transition. */
    .sap::before {
      content: "";
      position: absolute;
      inset: 0;
      z-index: 1;
      pointer-events: none;
      /* More stops, and the falloff starts before the copy column ends. Two
         widely spaced stops produced a visible vertical edge where the scrim
         stopped being opaque, and held the map too dark across the middle. */
      background: linear-gradient(
        90deg,
        var(--c-brown-deep) 0%,
        var(--c-brown-deep) 34%,
        rgba(58, 50, 44, 0.94) 41%,
        rgba(58, 50, 44, 0.78) 48%,
        rgba(58, 50, 44, 0.52) 57%,
        rgba(58, 50, 44, 0.3) 67%,
        rgba(58, 50, 44, 0.14) 77%,
        rgba(58, 50, 44, 0.04) 87%,
        rgba(58, 50, 44, 0) 95%
      );
    }

    .sap__panel {
      width: min(46%, 36rem);
      padding-block: calc(var(--section-y) * 1.15);
    }

    /* Over the map, bottom right, rather than a cream band beneath it. */
    .sap__credit {
      position: absolute;
      right: 0;
      bottom: 0;
      z-index: 2;
      padding: var(--s-2) var(--s-3);
      background: rgba(58, 50, 44, 0.55);
      color: var(--c-on-dark-muted);
    }
  }

/* ==========================================================
   ReviewWall.astro
   ========================================================== */

  .rw {
    background: var(--c-cream);
    padding-block: var(--section-y);
    overflow: hidden;
  }

  .rw__grid {
    display: grid;
    gap: var(--s-8);
  }

  /* ---------- aggregate ---------- */

  .rw__score {
    margin: 0;
    font-family: var(--font-display);
    font-size: clamp(4.5rem, 3rem + 8vw, 9rem);
    font-weight: var(--fw-light);
    line-height: 0.9;
    letter-spacing: -0.02em;
    color: var(--c-ink);
  }

  .rw__stars {
    margin: var(--s-4) 0 var(--s-3);
    font-size: var(--t-h3);
    letter-spacing: 0.22em;
    color: var(--c-taupe-deep);
  }

  .rw__source {
    margin: 0 0 var(--s-6);
    font-size: var(--t-small);
    color: var(--c-ink-muted);
  }

  .rw__source strong {
    font-family: var(--font-display);
    font-weight: var(--fw-medium);
    color: var(--c-ink);
  }

  .rw__chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-3);
    list-style: none;
    margin: 0 0 var(--s-6);
    padding: 0;
  }

  .rw__chips li {
    padding: var(--s-2) var(--s-4);
    border: 1px solid var(--c-taupe-deep);
    font-family: var(--font-display);
    font-size: var(--t-micro);
    /* Chips are labels, so weight 500 per the role table in tokens.css. These
       were inheriting 400 and were the last size+weight collision on the page. */
    font-weight: var(--fw-medium);
    letter-spacing: var(--ls-button);
    text-transform: uppercase;
    color: var(--c-ink-soft);
  }

  /* ---------- wall ---------- */

  .rw__wall {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s-4);
    /* Fade the top and bottom so cards enter and leave rather than pop. */
    mask-image: linear-gradient(
      to bottom,
      transparent 0,
      #000 8%,
      #000 92%,
      transparent 100%
    );
    -webkit-mask-image: linear-gradient(
      to bottom,
      transparent 0,
      #000 8%,
      #000 92%,
      transparent 100%
    );
  }

  .rw__col {
    height: 32rem;
    overflow: hidden;
  }

  .rw__track {
    display: grid;
    gap: var(--s-4);
    animation: rw-up var(--rw-speed, 80s) linear infinite;
    will-change: transform;
  }

  .rw__col[data-dir="down"] .rw__track {
    animation-name: rw-down;
  }

  /* -50% exactly, because the card list is rendered twice. */
  @keyframes rw-up {
    from {
      transform: translateY(0);
    }
    to {
      transform: translateY(-50%);
    }
  }

  @keyframes rw-down {
    from {
      transform: translateY(-50%);
    }
    to {
      transform: translateY(0);
    }
  }

  /* Stop so a review can be read. focus-within covers keyboard users. */
  .rw__wall:hover .rw__track,
  .rw__wall:focus-within .rw__track {
    animation-play-state: paused;
  }

  .rw__card {
    display: flex;
    flex-direction: column;
    gap: var(--s-3);
    margin: 0;
    padding: var(--s-5);
    background: var(--c-cream-light);
    border-top: 2px solid var(--c-taupe-deep);
  }

  .rw__cardStars {
    margin: 0;
    font-size: var(--t-micro);
    letter-spacing: 0.18em;
    color: var(--c-taupe-deeper);
  }

  .rw__card blockquote {
    margin: 0;
  }

  .rw__card blockquote p {
    margin: 0;
    font-size: var(--t-small);
    line-height: 1.6;
    color: var(--c-ink-soft);
    text-wrap: pretty;
  }

  .rw__card figcaption {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s-2);
    padding-top: var(--s-3);
    border-top: 1px solid var(--c-cream-deep);
  }

  .rw__author {
    font-family: var(--font-display);
    font-size: var(--t-micro);
    font-weight: var(--fw-medium);
    letter-spacing: var(--ls-label);
    text-transform: uppercase;
    color: var(--c-ink);
  }

  .rw__badge {
    font-size: var(--t-micro);
    color: var(--c-ink-muted);
  }

  /* ---------- responsive ---------- */

  @media (min-width: 620px) {
    .rw__wall {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    /* Third column only appears where there is width for it. */
    .rw__col:nth-child(3) {
      display: none;
    }
  }

  @media (min-width: 900px) {
    .rw__grid {
      grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
      gap: var(--s-9);
      align-items: center;
    }

    .rw__wall {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .rw__col:nth-child(3) {
      display: block;
    }

    .rw__col {
      height: 40rem;
    }
  }

  /* Reduced motion: no drift at all, just a normal scrollable column. */
  @media (prefers-reduced-motion: reduce) {
    .rw__col {
      height: 34rem;
      overflow-y: auto;
    }

    .rw__track {
      animation: none;
    }
  }

/* ==========================================================
   FaqList.astro
   ========================================================== */

  .faq__heading{
    margin-bottom: var(--s-6);
  }

  .faq__item{
    border-top: 1px solid var(--c-taupe-deep);
  }

  .faq__item:last-child{
    border-bottom: 1px solid var(--c-taupe-deep);
  }

  .faq summary{
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-5);
    padding: var(--s-5) 0;
    cursor: pointer;
    list-style: none;
  }

  .faq summary::-webkit-details-marker{
    display: none;
  }

  .faq__q{
    font-family: var(--font-display);
    font-size: var(--t-h4);
    font-weight: var(--fw-light);
    line-height: var(--lh-heading);
    color: var(--c-ink);
    text-wrap: balance;
  }

  /* Plus that becomes a minus when open. */
  .faq__icon{
    position: relative;
    flex: none;
    width: 16px;
    height: 16px;
  }

  .faq__icon::before,

  .faq__icon::after{
    content: "";
    position: absolute;
    inset: 50% 0 auto 0;
    height: 1.5px;
    background: var(--c-ink);
    transition: transform var(--dur-base) var(--ease-out);
  }

  .faq__icon::after{
    transform: rotate(90deg);
  }

  [open] .faq__icon::after{
    transform: rotate(0deg);
  }

  .faq__a{
    padding-bottom: var(--s-5);
  }

  .faq__a p{
    max-width: 68ch;
    margin: 0;
    color: var(--c-ink-muted);
    text-wrap: pretty;
  }

/* ==========================================================
   CTABand.astro
   ========================================================== */

  .cta__inner {
    display: grid;
    gap: var(--s-6);
  }

  /* Left-aligned with the actions in their own narrower column. Centring this
     made the page's last impression symmetrical, which undid the asymmetry
     everything above it had established. */
  @media (min-width: 860px) {
    .cta__inner {
      grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
      gap: var(--s-9);
      align-items: end;
    }
  }

  .cta__body {
    max-width: 46ch;
    margin: var(--s-5) 0 0;
    color: inherit;
    font-size: var(--t-lead);
    text-wrap: pretty;
  }

  .cta__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-4);
  }

  /* On the dark variant the outline button needs light borders. */
  .section--dark .cta__call {
    border-color: var(--c-on-dark-muted);
    color: var(--c-on-dark);
  }

  .section--dark .cta__call:hover {
    background: var(--c-on-dark);
    color: var(--c-black);
  }

/* ==========================================================
   AreaEEAT.astro
   ========================================================== */

  .eeat__layout {
    display: grid;
    gap: var(--s-7);
  }

  /* Uneven on purpose, and the trust column stays put while the list is read. */
  @media (min-width: 1000px) {
    .eeat__layout {
      grid-template-columns: minmax(0, 0.72fr) minmax(0, 1.28fr);
      gap: var(--s-9);
      align-items: start;
    }

    .eeat__who {
      position: sticky;
      top: calc(var(--s-9) + var(--s-4));
    }
  }

  /* ---------- who ---------- */

  .eeat__who {
    padding: var(--s-6);
    background: var(--c-cream);
  }

  .eeat__whoLabel {
    margin: 0 0 var(--s-5);
    font-family: var(--font-display);
    font-weight: var(--fw-medium);
    font-size: var(--t-micro);
    letter-spacing: var(--ls-label);
    text-transform: uppercase;
    color: var(--c-taupe-deeper);
  }

  .eeat__whoName {
    margin: 0;
    font-family: var(--font-display);
    font-weight: var(--fw-light);
    font-size: var(--t-h3);
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--c-ink);
  }

  .eeat__whoRole {
    margin: var(--s-2) 0 var(--s-4);
    font-size: var(--t-small);
    color: var(--c-ink-muted);
  }

  .eeat__whoBody {
    margin: 0 0 var(--s-5);
    font-size: var(--t-small);
    color: var(--c-ink-soft);
    text-wrap: pretty;
  }

  .eeat__proof {
    margin: 0 0 var(--s-5);
    padding-top: var(--s-4);
    border-top: 1px solid var(--c-taupe-deep);
  }

  .eeat__proof > div {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s-4);
    padding: var(--s-2) 0;
  }

  .eeat__proof dt {
    font-family: var(--font-display);
    font-weight: var(--fw-medium);
    font-size: var(--t-micro);
    letter-spacing: var(--ls-label);
    text-transform: uppercase;
    color: var(--c-taupe-deeper);
  }

  .eeat__proof dd {
    margin: 0;
    font-size: var(--t-small);
    text-align: right;
    color: var(--c-ink);
  }

  /* ---------- the five answers ---------- */

  .eeat__list {
    margin: 0;
  }

  .eeat__row {
    display: grid;
    gap: var(--s-3);
    padding: var(--s-5) 0;
    border-top: 1px solid var(--c-taupe-deep);
  }

  .eeat__row:last-child {
    border-bottom: 1px solid var(--c-taupe-deep);
  }

  @media (min-width: 720px) {
    .eeat__row {
      grid-template-columns: minmax(0, 0.44fr) minmax(0, 1fr);
      gap: var(--s-6);
    }
  }

  .eeat__row dt {
    font-family: var(--font-display);
    font-weight: var(--fw-light);
    font-size: var(--t-h4);
    line-height: var(--lh-heading);
    letter-spacing: 0.02em;
    color: var(--c-ink);
    text-wrap: balance;
  }

  .eeat__row dd {
    margin: 0;
    font-size: var(--t-small);
    line-height: 1.65;
    color: var(--c-ink-soft);
    text-wrap: pretty;
  }

  .eeat__row a {
    color: var(--c-navy);
    font-weight: var(--fw-semibold);
  }

  .eeat__note {
    margin: var(--s-3) 0 0;
    color: var(--c-ink-muted);
  }

  .eeat__services {
    display: grid;
    gap: var(--s-2);
    list-style: none;
    margin: 0;
    padding: 0;
  }

/* ==========================================================
   QuoteForm.astro
   ========================================================== */

  .qf {
    background: var(--c-cream);
    padding: var(--s-6);
  }

  @media (min-width: 700px) {
    .qf {
      padding: var(--s-8);
    }
  }

  .qf__honey {
    position: absolute;
    left: -9999px;
  }

  /* ---- progress ---- */

  .qf__progress {
    margin-bottom: var(--s-6);
  }

  .qf__bar {
    height: 2px;
    background: var(--c-taupe);
  }

  .qf__bar span {
    display: block;
    height: 100%;
    background: var(--c-navy);
    transition: width var(--dur-base) var(--ease-out);
  }

  .qf__count {
    margin: var(--s-2) 0 0;
    font-family: var(--font-display);
    font-weight: var(--fw-medium);
    font-size: var(--t-micro);
    letter-spacing: var(--ls-label);
    text-transform: uppercase;
    color: var(--c-ink-muted);
  }

  .qf__count b {
    font-weight: var(--fw-medium);
    color: var(--c-ink);
  }

  /* ---- steps ---- */

  .qf__step {
    margin: 0;
    padding: 0;
    border: 0;
  }

  /* Only applied once JS confirms it can manage steps. */
  .qf[data-js] .qf__step[hidden] {
    display: none;
  }

  .qf__step + .qf__step {
    margin-top: var(--s-8);
    padding-top: var(--s-7);
    border-top: 1px solid var(--c-taupe-deep);
  }

  .qf[data-js] .qf__step + .qf__step {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
  }

  .qf__legend {
    padding: 0;
    font-family: var(--font-display);
    font-size: var(--t-h3);
    font-weight: var(--fw-light);
    line-height: var(--lh-heading);
    color: var(--c-ink);
    text-wrap: balance;
  }

  .qf__help {
    margin: var(--s-3) 0 var(--s-5);
    font-size: var(--t-small);
    color: var(--c-ink-muted);
  }

  /* ---- choices ---- */

  .qf__choices {
    display: grid;
    gap: var(--s-3);
    margin-bottom: var(--s-6);
  }

  .qf__choices--grid {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
  }

  .qf__choice {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    padding: var(--s-4);
    background: var(--c-cream-light);
    border: 1px solid var(--c-cream-deep);
    cursor: pointer;
    transition:
      border-color var(--dur-fast) var(--ease-out),
      background-color var(--dur-fast) var(--ease-out);
  }

  .qf__choice:hover {
    border-color: var(--c-border-ui);
  }

  /* Whole tile reads as selected, not just the dot. */
  .qf__choice:has(input:checked) {
    border-color: var(--c-navy);
    background: #fff;
  }

  .qf__choice:has(input:focus-visible) {
    outline: 2px solid var(--c-focus);
    outline-offset: 2px;
  }

  .qf__choice input {
    flex: none;
    accent-color: var(--c-navy);
    width: 18px;
    height: 18px;
  }

  .qf__choiceLabel {
    display: block;
    font-family: var(--font-display);
    font-weight: var(--fw-medium);
    font-size: var(--t-small);
    letter-spacing: 0.04em;
    color: var(--c-ink);
  }

  .qf__choiceHint {
    display: block;
    margin-top: 2px;
    font-family: var(--font-body);
    font-size: var(--t-micro);
    letter-spacing: 0;
    color: var(--c-ink-muted);
  }

  /* ---- fields ---- */

  .qf__row {
    display: grid;
    gap: var(--s-4);
  }

  @media (min-width: 560px) {
    .qf__row {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }
  }

  .qf__field {
    display: grid;
    gap: var(--s-2);
    margin-bottom: var(--s-4);
  }

  .qf__field label {
    font-family: var(--font-display);
    font-weight: var(--fw-medium);
    font-size: var(--t-micro);
    letter-spacing: var(--ls-label);
    text-transform: uppercase;
    color: var(--c-ink-soft);
  }

  .qf__field span[aria-hidden] {
    color: var(--c-error);
  }

  .qf__field input,
  .qf__field select,
  .qf__field textarea {
    width: 100%;
    padding: var(--s-3) var(--s-4);
    background: var(--c-cream-light);
    /* A control's edge must clear 3:1 (WCAG 1.4.11), which the decorative
       hairline colour does not. */
    border: 1px solid var(--c-border-ui);
    border-radius: var(--radius);
    font-family: var(--font-body);
    font-size: var(--t-body); /* 16px+ so iOS does not zoom on focus */
    color: var(--c-ink);
  }

  .qf__field textarea {
    resize: vertical;
  }

  .qf__field input:focus,
  .qf__field select:focus,
  .qf__field textarea:focus {
    outline: 2px solid var(--c-focus);
    outline-offset: 1px;
    border-color: var(--c-navy);
  }

  /* ---- nav ---- */

  .qf__next,
  .qf__nav {
    margin-top: var(--s-2);
  }

  .qf__nav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-3);
  }

  .qf__fine {
    margin: var(--s-5) 0 0;
    font-size: var(--t-micro);
    color: var(--c-ink-muted);
  }

  .qf__fine a {
    color: var(--c-navy);
  }

/* ==========================================================
   ConsultationModal.astro
   ========================================================== */

  /* ============================================================
     Shell
     ============================================================ */

  .cm {
    /* A dialog is width:fit-content and margin:auto by default; both need
       overriding or a one-line question renders a narrow column. */
    width: min(100%, var(--container-narrow));
    max-width: none;
    /* Not 100dvh. The last step is tall enough to hit the cap, and at exactly
       100dvh the panel wedges against the top and bottom edges and stops reading
       as a card floating over the page. The inherited margin:auto spreads what
       this leaves over, so it stays centred. */
    max-height: calc(100dvh - var(--s-8));
    padding: 0;
    border: 0;
    border-radius: var(--radius);
    background: var(--c-cream);
    color: var(--c-ink-soft);
    /* The only element on the site that floats over arbitrary content. */
    box-shadow: var(--shadow-lg);
  }

  /* Scoped to [open], never bare .cm — `display` on the dialog itself overrides
     the UA's `dialog:not([open]) { display: none }`, and a bare rule here would
     leave the form permanently on the page. The dialog has to be the flex
     container so its max-height is what bounds the scroll area. */
  .cm[open] {
    display: flex;
    flex-direction: column;
  }

  /* Mobile: a sheet, not a card. A centred card at 390px wastes the edges and
     puts the keyboard over the buttons. */
  @media (max-width: 39.9375rem) {
    .cm {
      width: 100%;
      height: 100dvh;
      max-height: none;
      margin: 0;
    }
  }

  .cm::backdrop {
    /* Her black, not a generic grey, and dark enough that the panel reads as
       the only live thing on screen. */
    background: rgba(20, 17, 15, 0.78);
  }

  /* Both animate opacity/transform only, and both are skipped wholesale under
     prefers-reduced-motion via the duration tokens. allow-discrete is what lets
     a display:none element transition in at all. */
  @media (prefers-reduced-motion: no-preference) {
    .cm,
    .cm::backdrop {
      transition:
        opacity var(--dur-base) var(--ease-out),
        transform var(--dur-base) var(--ease-out),
        display var(--dur-base) allow-discrete,
        overlay var(--dur-base) allow-discrete;
    }

    .cm,
    .cm::backdrop {
      opacity: 0;
    }

    .cm {
      transform: translateY(var(--s-5));
    }

    .cm[open],
    .cm[open]::backdrop {
      opacity: 1;
    }

    .cm[open] {
      transform: none;
    }

    @starting-style {
      .cm[open],
      .cm[open]::backdrop {
        opacity: 0;
      }

      .cm[open] {
        transform: translateY(var(--s-5));
      }
    }
  }

  .cm__form {
    display: flex;
    flex-direction: column;
    /* Grows to fill the dialog so the footer sits at the bottom of the mobile
       sheet. min-height:0 is load-bearing: a flex item's default min-height is
       auto, which refuses to shrink below its content, and without it the body
       below never becomes a scroll container — it just pushes the footer off. */
    flex: 1 1 auto;
    min-height: 0;
  }

  .cm__honey {
    position: absolute;
    left: -9999px;
  }

  /* ============================================================
     Head
     ============================================================ */

  .cm__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--s-4);
    padding: var(--s-5) var(--s-5) var(--s-4);
  }

  .cm__eyebrow,
  .cm__count {
    margin: 0;
    font-family: var(--font-display);
    font-weight: var(--fw-medium);
    font-size: var(--t-micro);
    letter-spacing: var(--ls-label);
    text-transform: uppercase;
  }

  .cm__eyebrow {
    color: var(--c-ink);
  }

  .cm__count {
    margin-top: var(--s-2);
    color: var(--c-ink-muted);
  }

  .cm__count b {
    font-weight: var(--fw-medium);
    color: var(--c-ink);
  }

  /*
   * THE CLOSE CONTROL. It was a 14px hairline cross on the page background with
   * no border and no fill — a 44px hit area is worth nothing if there is nothing
   * on screen telling you the 44px is there. Doug's read of it on a phone was
   * "a bad X on the right-hand side, it was all bad", and he was right: it did
   * not look like a button, so the only obvious way out of a six-step form was
   * the back gesture.
   *
   * It is now a drawn control — a filled tile with a border, on her cream rather
   * than a grey, and a glyph at 18px instead of 14px. Square, not a circle:
   * --radius is 0 across this UI and circles are off-brand here.
   */
  .cm__close {
    flex: none;
    display: grid;
    place-items: center;
    /* 44px, so it is a real target on a phone rather than a 14px glyph. */
    width: 2.75rem;
    height: 2.75rem;
    margin: 0;
    padding: 0;
    background: var(--c-cream-light);
    border: 1px solid var(--c-border-ui);
    border-radius: var(--radius);
    color: var(--c-ink);
    cursor: pointer;
    transition:
      color var(--dur-fast) var(--ease-out),
      background-color var(--dur-fast) var(--ease-out),
      border-color var(--dur-fast) var(--ease-out);
  }

  .cm__close:hover {
    background: var(--c-cream-deep);
    border-color: var(--c-ink-soft);
    color: var(--c-ink);
  }

  .cm__close svg {
    width: 1.125rem;
    height: 1.125rem;
  }

  .cm__bar {
    flex: none;
    height: 2px;
    background: var(--c-taupe);
  }

  .cm__bar span {
    display: block;
    height: 100%;
    background: var(--c-navy);
    transition: width var(--dur-base) var(--ease-out);
  }

  /* ============================================================
     Body
     ============================================================ */

  .cm__body {
    /* The scroll container. Only this scrolls — never the page behind, and never
       the head or footer, so the progress bar and Continue stay put. */
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: var(--s-6) var(--s-5);
  }

  @media (min-width: 40rem) {
    .cm__head {
      padding: var(--s-6) var(--s-6) var(--s-4);
    }

    .cm__body {
      padding: var(--s-7) var(--s-6);
    }
  }

  .cm__step {
    margin: 0;
    padding: 0;
    border: 0;
  }

  .cm__step[hidden] {
    display: none;
  }

  .cm__legend {
    padding: 0;
    /* One question per screen, so it gets to be a real heading. */
    font-family: var(--font-display);
    font-size: var(--t-h2);
    font-weight: var(--fw-light);
    line-height: var(--lh-heading);
    letter-spacing: var(--ls-display);
    color: var(--c-ink);
    text-wrap: balance;
  }

  /* The legend takes focus on every step change so the question is announced.
     It is not an interactive control, so the standard focus ring would be a
     lie — this suppresses it without suppressing it for anything real. */
  .cm__legend:focus-visible {
    outline: none;
  }

  .cm__help {
    margin: var(--s-4) 0 0;
    font-size: var(--t-small);
    color: var(--c-ink-muted);
  }

  /* ============================================================
     Choices
     ============================================================ */

  .cm__choices {
    display: grid;
    gap: var(--s-3);
    margin-top: var(--s-6);
  }

  /*
   * align-items: flex-start, not center.
   *
   * Four of the six steps have at least one option that wraps to two lines at
   * 390px — "Home Organizing & Decluttering" and "Unsure, would like to chat
   * details." both do. Centering put the radio halfway down a two-line block
   * while its single-line neighbours had theirs level with the text, so a column
   * of four tiles had radios at three different heights. It read as broken
   * rather than as a choice.
   */
  .cm__choice {
    display: flex;
    align-items: flex-start;
    gap: var(--s-4);
    padding: var(--s-4);
    background: var(--c-cream-light);
    border: 1px solid var(--c-border-ui);
    cursor: pointer;
    transition:
      border-color var(--dur-fast) var(--ease-out),
      background-color var(--dur-fast) var(--ease-out);
  }

  .cm__choice:hover {
    background: #fff;
  }

  .cm__choice:has(input:checked) {
    border-color: var(--c-navy);
    background: #fff;
  }

  .cm__choice:has(input:focus-visible) {
    outline: 2px solid var(--c-focus);
    outline-offset: 2px;
  }

  .cm__choice input {
    flex: none;
    width: 18px;
    height: 18px;
    /* Half the difference between the label's line box (--t-small at the body
       line-height, ~26px) and the 18px control, so the radio stays optically
       centred on the FIRST line now that the tile aligns to the top. */
    margin-top: 4px;
    accent-color: var(--c-navy);
  }

  .cm__choiceLabel {
    font-family: var(--font-display);
    font-weight: var(--fw-medium);
    font-size: var(--t-small);
    letter-spacing: 0.04em;
    color: var(--c-ink);
  }

  .cm__choice--sm .cm__choiceLabel {
    font-family: var(--font-body);
    font-weight: var(--fw-regular);
    font-size: var(--t-small);
    letter-spacing: 0;
    color: var(--c-ink-soft);
  }

  /* ---------- the conditional referral field ----------
     Hidden until Referral is the checked radio in this step. CSS only: the field
     is optional, so nothing has to toggle `required` and no JS branch exists to
     fall out of sync with the markup. */
  /* Both selectors name two classes on purpose. The element is
     `cm__field cm__referral`, and .cm__field sets display:grid further down this
     stylesheet — at equal specificity source order would win and the field would
     never hide at all, which is exactly what happened the first time. */
  .cm__field.cm__referral {
    display: none;
  }

  .cm__step:has(input[value="Referral"]:checked) .cm__field.cm__referral {
    display: grid;
    margin-top: var(--s-5);
  }

  /* ============================================================
     Fields
     ============================================================ */

  .cm__row {
    display: grid;
    gap: var(--s-4);
  }

  @media (min-width: 30rem) {
    .cm__row {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }
  }

  .cm__field {
    display: grid;
    gap: var(--s-2);
    margin-top: var(--s-5);
  }

  .cm__field label {
    font-family: var(--font-display);
    font-weight: var(--fw-medium);
    font-size: var(--t-micro);
    letter-spacing: var(--ls-label);
    text-transform: uppercase;
    color: var(--c-ink-soft);
  }

  .cm__field span[aria-hidden],
  .cm__consent legend span[aria-hidden] {
    color: var(--c-error);
  }

  .cm__field input,
  .cm__field textarea {
    width: 100%;
    padding: var(--s-3) var(--s-4);
    background: var(--c-cream-light);
    border: 1px solid var(--c-border-ui);
    border-radius: var(--radius);
    font-family: var(--font-body);
    font-size: var(--t-body); /* 16px+ so iOS does not zoom the sheet on focus */
    color: var(--c-ink);
  }

  .cm__field textarea {
    resize: vertical;
  }

  .cm__field input:focus,
  .cm__field textarea:focus {
    outline: 2px solid var(--c-focus);
    outline-offset: 1px;
    border-color: var(--c-navy);
  }

  .cm__hint {
    margin: 0;
    font-size: var(--t-micro);
    color: var(--c-ink-muted);
  }

  .cm__consent {
    display: grid;
    gap: var(--s-3);
    margin: var(--s-6) 0 0;
    padding: 0;
    border: 0;
  }

  .cm__consent legend {
    padding: 0;
    font-family: var(--font-display);
    font-weight: var(--fw-medium);
    font-size: var(--t-micro);
    letter-spacing: var(--ls-label);
    text-transform: uppercase;
    color: var(--c-ink-soft);
  }

  /* ============================================================
     Foot
     ============================================================ */

  .cm__foot {
    flex: none;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-3);
    padding: var(--s-4) var(--s-5) max(var(--s-5), env(safe-area-inset-bottom, 0px));
    background: var(--c-cream-light);
    border-top: 1px solid var(--c-cream-deep);
  }

  @media (min-width: 40rem) {
    .cm__foot {
      padding-inline: var(--s-6);
    }
  }

  .cm__foot [hidden] {
    display: none;
  }

  /*
   * CONTINUE TAKES THE ROOM THAT IS THERE.
   *
   * On step one there is nothing to go back to, so Back is display:none and
   * Continue was left sitting at its intrinsic 154px against the left edge of a
   * 390px bar with 200px of empty cream beside it. The single action on the
   * screen looked like an afterthought.
   *
   * flex: 1 on the two forward buttons and flex: none on Back means Continue
   * fills the bar when it is alone and takes everything Back does not when both
   * are up — which is also the correct hierarchy, since Back is the cheaper of
   * the two and should not be the same size as the one that moves you on.
   */
  .cm__back {
    flex: 0 0 auto;
  }

  .cm__foot [data-next],
  .cm__foot [data-submit] {
    flex: 1 1 auto;
  }

  .cm__fine {
    flex: 1 1 100%;
    margin: 0;
    font-size: var(--t-micro);
    color: var(--c-ink-muted);
  }

  .cm__fine a {
    color: var(--c-navy);
  }

  @media (min-width: 40rem) {
    .cm__fine {
      flex: 1 1 auto;
      text-align: right;
    }
  }

/* ==========================================================
   BackToTop.astro
   ========================================================== */

  /* An invisible measuring stick from the top of the document down 75vh. body is
     not positioned, so top:0 resolves against the initial containing block and
     this stays anchored to the document regardless of where it sits in the DOM.
     Zero width and no pointer events, so it cannot affect layout or hit-testing. */
  .totop__ruler {
    position: absolute;
    top: 0;
    left: 0;
    width: 1px;
    height: 75vh;
    pointer-events: none;
  }

  /* a.totop, not .totop: Astro compiles scoped selectors with :where(), which
     contributes no specificity, so a bare .totop would tie with .btn and the
     winner would come down to injection order. The element selector settles it. */
  a.totop {
    position: fixed;
    right: var(--gutter);
    /* env() so the tile clears the iPhone home indicator rather than sitting
       under it. max() keeps the normal inset everywhere else. */
    bottom: max(var(--s-5), env(safe-area-inset-bottom, 0px));
    /* Below --z-nav (200): the sticky header must always win. */
    z-index: var(--z-sticky);
    /* .btn's 16/32 padding is sized for in-flow calls to action. A floating
       shortcut wants to be smaller than those, and 12/16 around 14px uppercase
       still clears the 44px touch target. */
    padding: var(--s-3) var(--s-4);
    /* The one place a shadow is right: this is the only element that genuinely
       floats over arbitrary content, so it has no offset panel to sit against. */
    box-shadow: var(--shadow-md);
    /* Hidden state. visibility, not opacity alone, so the link leaves the tab
       order while it is off screen instead of being a focusable ghost. */
    opacity: 0;
    visibility: hidden;
    transform: translateY(var(--s-2));
    /* Overrides .btn's transition to add opacity and visibility. Durations are
       tokens, so prefers-reduced-motion collapses all of this to 1ms. */
    transition:
      opacity var(--dur-base) var(--ease-out),
      transform var(--dur-base) var(--ease-out),
      visibility var(--dur-base) linear,
      background-color var(--dur-base) var(--ease-out);
  }

  a.totop.is-visible {
    opacity: 1;
    visibility: visible;
    transform: none;
  }

  /*
   * NOT ON A PHONE AT ALL.
   *
   * This used to lift clear of the mobile CTA bar, which occupies the same
   * corner below 48rem. Clearing the bar only moved the problem up the screen:
   * the tile then floated over the body copy instead, and on a 390px viewport
   * it covered the last few words of whatever paragraph happened to be there.
   * Caught on /service-areas/plano-professional-organizers/, where it sat across
   * the closets blurb.
   *
   * Two floating controls stacked in one corner of a phone is one too many, and
   * of the two the CTA bar is the one worth keeping. Scrolling up is not a
   * problem a phone user has — it is a desktop convenience, so it stays a
   * desktop convenience.
   */
  @media (max-width: 47.9375rem) {
    a.totop {
      display: none;
    }
  }

  /* .btn:active nudges down 1px. That has to be restated here because the
     reveal owns transform and would otherwise cancel the press feedback. */
  a.totop.is-visible:active {
    transform: translateY(1px);
  }

  .totop__arrow {
    width: 0.75em;
    height: 0.75em;
  }

  /* No script, no observer, so nothing would ever reveal it. Browsers that
     support this get a permanently visible, fully working link; the rest lose a
     convenience shortcut, not content. */
  @media (scripting: none) {
    a.totop {
      opacity: 1;
      visibility: visible;
      transform: none;
    }
  }

  @media print {
    a.totop {
      display: none;
    }
  }

/* ==========================================================
   MobileCtaBar.astro
   ========================================================== */

  .mcb {
    /* Hidden by default so the desktop layout never pays for it — no fixed
       element to composite, and no chance of it flashing on a wide screen
       before a media query applies. */
    display: none;
  }

  @media (max-width: 47.9375rem) {
    .mcb {
      display: grid;
      /* Not 1fr 1fr. "Book Discovery Call" is more than twice the length of
         "Call Now", and equal halves either wrapped it to two lines or forced
         the type down a step. Call is the cheaper action and reads fine narrow. */
      grid-template-columns: 3fr 5fr;
      position: fixed;
      left: 0;
      right: 0;
      bottom: 0;
      /* Under --z-nav (200) so the sticky header still wins, over --z-raised. */
      z-index: var(--z-sticky);
      /* The tabs are --mobile-bar-h tall; the inset is extra ground below them
         so the labels sit above the iPhone home indicator rather than under it. */
      padding-bottom: env(safe-area-inset-bottom, 0px);
      background: var(--c-black);
      /* Depth upward only. The bar has nothing below it to cast onto. */
      box-shadow: 0 -4px 16px rgba(29, 30, 32, 0.18);
    }
  }

  .mcb__tab {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--s-2);
    height: var(--mobile-bar-h);
    padding-inline: var(--s-3);
    font-family: var(--font-display);
    font-weight: var(--fw-medium);
    font-size: var(--t-micro);
    /* --ls-button (0.1em) pushed the 19-character booking label to two lines at
       320px. This keeps the letterspaced look without the wrap. */
    letter-spacing: 0.04em;
    text-transform: uppercase;
    text-decoration: none;
    /* Long labels must not wrap inside a 56px-tall tab. */
    white-space: nowrap;
    transition: background-color var(--dur-fast) var(--ease-out);
  }

  /* Call is the secondary action: her black, cream text at 17.26:1. */
  .mcb__tab--call {
    background: var(--c-black);
    color: var(--c-on-dark);
  }

  .mcb__tab--call:active {
    background: var(--c-black-soft);
  }

  /* Booking is the primary: the action colour, cream on it well clear of AA.
     Against the black Call tab beside it the warm/neutral split does the work of
     telling you which of the two is the main thing. */
  .mcb__tab--quote {
    background: var(--c-action);
    color: var(--c-on-dark);
  }

  .mcb__tab--quote:active {
    background: var(--c-action-hover);
  }

  /* Focus rings are drawn inside. The default outline-offset:3px from global.css
     would put half the ring off the bottom of the screen. */
  .mcb__tab:focus-visible {
    outline: 2px solid var(--c-on-dark);
    outline-offset: -5px;
  }

  .mcb__icon {
    width: 0.875rem;
    height: 0.875rem;
    flex: none;
  }

  /* Narrow phones. At 320px the two labels plus their padding want 336px in a
     320px bar, so both ran edge to edge with zero slack — not technically
     overflowing, which is exactly why the gate's overflow check alone was not
     enough to call it fitting. Trimming the padding, the icon gap and the
     tracking frees ~27px without dropping the type below --t-micro or hiding
     the phone icon. */
  @media (max-width: 23.4375rem) {
    .mcb__tab {
      gap: var(--s-1);
      padding-inline: var(--s-2);
      letter-spacing: 0.02em;
    }
  }

  @media print {
    .mcb {
      display: none;
    }
  }

/* ==========================================================
   BaseLayout.astro
   ========================================================== */

        .reveal {
          opacity: 1 !important;
          transform: none !important;
        }
      

  main.pad-top {
    padding-top: calc(var(--nav-h) + var(--s-7));
  }


/* ==========================================================
   SHARED, lifted out of page bundles by extract-css.mjs

   These classes are authored inside a page's <style> block but rendered by
   more than one template. Left in a page bundle they load on one page and
   are missing on the others — which is exactly how the service pages ended
   up with an unstyled "How it works" grid.
   ========================================================== */

/* ---- shared, lifted from index.astro ---- */


  /* ---------------- steps ---------------- */


  .steps {
    display: grid;
    gap: var(--s-6);
    list-style: none;
    margin: 0;
    padding: 0;
    counter-reset: step;
  }
@media (min-width: 700px) {
    .steps {
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: var(--s-7);
    }
  }
@media (min-width: 1100px) {
    /* Stepped down to the right. The section describes a sequence, so a diagonal
       says "progression" where four level columns said "list". */
    .steps {
      grid-template-columns: 1.1fr 1fr 1fr 1.04fr;
      gap: var(--s-5);
      align-items: start;
    }

    .steps__item:nth-child(2) { margin-top: var(--s-5); }
    .steps__item:nth-child(3) { margin-top: calc(var(--s-5) * 2); }
    .steps__item:nth-child(4) { margin-top: calc(var(--s-5) * 3); }
  }


  .steps__item {
    padding-top: var(--s-4);
    border-top: 1px solid var(--c-taupe-deep);
  }


  .steps__n {
    display: block;
    margin-bottom: var(--s-3);
    font-family: var(--font-display);
    font-weight: var(--fw-medium);
    font-size: var(--t-small);
    letter-spacing: var(--ls-label);
    color: var(--c-taupe-deeper);
  }


  .steps__title {
    margin-bottom: var(--s-3);
  }


  .steps__body {
    margin: 0;
    font-size: var(--t-small);
    color: var(--c-ink-muted);
    text-wrap: pretty;
  }


  /* ---------------- objections: bento ---------------- */


  .bento {
    display: grid;
    gap: var(--s-4);
  }


  .bento__cell {
    padding: var(--s-6);
    background: var(--c-cream);
    border-top: 2px solid var(--c-taupe-deep);
  }


  /* The feature tile carries the objection that actually blocks bookings, so it
     gets the deeper ground and the accent rule. */
  .bento__cell--feature {
    background: var(--c-cream-light);
    border-top-color: var(--c-navy);
  }


  .bento__q {
    margin: 0 0 var(--s-4);
    font-family: var(--font-display);
    font-size: var(--t-h4);
    font-weight: var(--fw-light);
    line-height: var(--lh-heading);
    letter-spacing: 0;
    text-transform: none;
    color: var(--c-ink);
    text-wrap: balance;
  }


  .bento__cell--feature .bento__q {
    font-size: var(--t-h3);
  }


  .bento__cell p {
    margin: 0;
    font-size: var(--t-small);
    color: var(--c-ink-soft);
    text-wrap: pretty;
  }


  .bento__cell p + p {
    margin-top: var(--s-4);
  }


  .bento__cell a {
    color: var(--c-navy);
    font-weight: var(--fw-semibold);
  }
@media (min-width: 700px) and (max-width: 1039px) {
    .bento {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .bento__cell--wide {
      grid-column: span 2;
    }
  }
@media (min-width: 1040px) {
    .bento {
      grid-template-columns: 1.15fr 1fr 1fr;
      grid-template-areas:
        "feature wide wide"
        "feature small1 small2";
      gap: var(--s-5);
    }

    .bento__cell--feature {
      grid-area: feature;
      display: flex;
      flex-direction: column;
      justify-content: center;
      padding: var(--s-8) var(--s-7);
    }

    .bento__cell--wide {
      grid-area: wide;
    }

    .bento__cell:nth-of-type(3) {
      grid-area: small1;
    }

    .bento__cell:nth-of-type(4) {
      grid-area: small2;
    }
  }


  /* ---------------- faq ---------------- */


  .faq__cols {
    display: grid;
    /* --split-gap, the branding constant. This was a literal --s-8; every
       two-column split on the site takes the same gutter. See tokens.css. */
    gap: 0 var(--split-gap);
  }
@media (min-width: 48rem) {
    .faq__cols {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }
  }