/* =====================================================================
   Homepage (untitled; v14 previews the name WJP Studio), v4: original attitude, new substance.
   Loaded AFTER styles.css. The hero, the Book a Call bar, the
   Subscribe. Request. Receive. bands and the one-liners use the
   ORIGINAL styles.css scale untouched. This file only adds the
   wordmark, black/white links, The Offer and The How layouts.
   ===================================================================== */

/* ---- v35 navy, part 1: styles.css overrides (generated) ---------------------
 Every styles.css colour declaration (color, background, border colours,
 fill, stroke) re-declared in source order, so the cascade among styles.css
 rules is unchanged, with every black or near-black value (black,
 #000, hsla(0,0%,0%,1), the #1d1d1f ink hsla(240,3.33%,11.76%,1), #141414,
 #1e1e1f and the old ink #060c22) re-declared with the same selector and
 media query, set to Public Network navy #060c21 (PN interface/design.md,
 --color-fg). Shadows and alpha tints are left alone. Placed first in this
 file so the later first-pass.css rules keep winning where they did.    */
  :root { --black-alt: #060c21; --black-blue: #060c21; --color: #060c21; }
  body { color: var(--black-alt,#060c21); background: #fff; }
  a { color: inherit; }
  button { background: none; }
  .home_testimonial_rating-icon { color: #060c21; }
  .text-color-graytrue300 { color: hsla(0, 0.00%, 83.92%, 1.00); }
  .rl-styleguide_color.is-gray300 { background-color: #d0d5dd; }
  .heading-32 { color: hsla(0, 0.00%, 99.22%, 1.00); }
  .form-input { border-top-color: #060c21; border-right-color: #060c21; border-bottom-color: #060c21; border-left-color: #060c21; background-color: hsla(0, 0.00%, 100.00%, 1.00); color: #060c21; }
  .background-color-graytrue100 { background-color: hsla(0, 0.00%, 96.08%, 1.00); }
  .text-color-gray300 { color: #d0d5dd; }
  .button.is-link.is-alternate { background-color: transparent; color: hsla(0, 0.00%, 100.00%, 1.00); }
  .home_latest-projects_slider { background-color: transparent; }
  .home_testimonial_divider { background-color: #060c21; }
  .rl-styleguide_color.is-gray800 { background-color: hsla(214.28571428571428, 32.56%, 16.86%, 1.00); }
  .rl-styleguide_paste-text { border-top-color: hsla(0, 0.00%, 0.00%, 0.15); border-right-color: hsla(0, 0.00%, 0.00%, 0.15); border-bottom-color: hsla(0, 0.00%, 0.00%, 0.15); border-left-color: hsla(0, 0.00%, 0.00%, 0.15); color: hsla(0, 0.00%, 0.00%, 0.50); }
  .background-color-graytrue500 { background-color: hsla(0, 0.00%, 45.10%, 1.00); }
  .is-white { background-color: hsla(0, 0.00%, 100.00%, 1.00); }
  .home_latest-projects_arrow { border-top-color: #060c21; border-right-color: #060c21; border-bottom-color: #060c21; border-left-color: #060c21; background-color: hsla(0, 0.00%, 100.00%, 1.00); }
  .rl-styleguide_color.is-gray100 { background-color: #f2f4f7; }
  .section_one-liner2.background-color-graytrue900 { background-color: #060c21; background-image: linear-gradient(to bottom, #060c21, #fcfcfc); }
  .book-call-text { color: #060c21; }
  .background-color-graytrue25 { background-color: hsla(0, 0.00%, 98.82%, 1.00); }
  .heading-17 { color: hsla(0, 0.00%, 100.00%, 1.00); }
  .button.is-secondary.is-alternate { border-top-color: hsla(0, 0.00%, 100.00%, 1.00); border-right-color: hsla(0, 0.00%, 100.00%, 1.00); border-bottom-color: hsla(0, 0.00%, 100.00%, 1.00); border-left-color: hsla(0, 0.00%, 100.00%, 1.00); background-color: transparent; color: hsla(0, 0.00%, 100.00%, 1.00); }
  .background-color-gray900 { background-color: hsla(219.99999999999997, 42.86%, 10.98%, 1.00); }
  .section_book-cta { background-color: #060c21; }
  .footer_credit-text { color: hsla(0, 0.00%, 100.00%, 1.00); }
  .heading-9 { color: #060c21; }
  .pricing5_plan { border-top-color: #060c21; border-right-color: #060c21; border-bottom-color: #060c21; border-left-color: #060c21; }
  .image-overlay-layer { background-color: hsla(208.00000000000003, 0.00%, 0.00%, 0.50); }
  .background-color-gray { background-color: hsla(0, 0.00%, 99.22%, 1.00); }
  .footer_legal-link { color: hsla(0, 0.00%, 99.22%, 1.00); }
  .heading-14 { color: hsla(0, 0.00%, 100.00%, 1.00); }
  .text-color-gray25 { color: #fcfcfd; }
  .heading-style-h6 { color: #060c21; }
  .button.max-width-full { border-top-color: #060c21; border-right-color: #060c21; border-bottom-color: #060c21; border-left-color: #060c21; background-color: #060c21; color: #f5f5f7; }
  .section_one-liner4 { background-color: #060c21; }
  .navbar { background-color: #fcfcfc; }
  .most-popular_tag-wrapper { background-color: hsla(216.9230769230769, 65.55%, 46.67%, 1.00); }
  .add-ons-card { background-color: hsla(0, 0.00%, 100.00%, 1.00); }
  .layout32_image { border-top-color: #060c21; border-right-color: #060c21; border-bottom-color: #060c21; border-left-color: #060c21; }
  .cta_bar { background-color: hsla(0, 0.00%, 99.22%, 1.00); }
  .text-color-gray600 { color: #475467; }
  .rl-styleguide_color.is-graytrue900 { background-color: #060c21; }
  .text-color-graytrue50 { color: hsla(0, 0.00%, 98.04%, 1.00); }
  .heading-13 { color: hsla(0, 0.00%, 100.00%, 1.00); }
  .rl-styleguide_color.is-graytrue800 { background-color: hsla(0, 0.00%, 16.08%, 1.00); }
  .text-color-gray700 { color: #344054; }
  .text-color-graytrue200 { color: hsla(0, 0.00%, 89.80%, 1.00); }
  .the-pricing_subscription-card-small { background-color: hsla(0, 0.00%, 100.00%, 1.00); }
  .footer_link { color: #f5f5f7; }
  .rl-styleguide_color.is-graytrue400 { background-color: hsla(0, 0.00%, 63.92%, 1.00); }
  .is-gray { background-color: hsla(0, 0.00%, 99.22%, 1.00); }
  .background-color-black { background-color: #060c21; color: hsla(0, 0.00%, 100.00%, 1.00); }
  .text-size-large { color: #060c21; }
  .section_the-add-ons { background-color: #060c21; }
  .rl-styleguide_color.is-gray600 { background-color: hsla(215.625, 18.39%, 34.12%, 1.00); }
  .rl-styleguide_color.is-graytrue700 { background-color: hsla(0, 0.00%, 25.88%, 1.00); }
  .faq_margin-font-size { color: #060c21; }
  .rl-styleguide-message-fixed { background-color: hsla(0, 0.00%, 100.00%, 1.00); }
  .text-color-graytrue25 { color: hsla(0, 0.00%, 98.82%, 1.00); }
  .is-black { background-color: #060c21; }
  .preloader { background-color: #060c21; }
  .rl-styleguide_color.is-gray700 { background-color: hsla(217.5, 23.53%, 26.67%, 1.00); }
  .background-color-gray400 { background-color: #98a2b3; }
  .rl-styleguide_color.is-graytrue25 { background-color: hsla(0, 0.00%, 98.82%, 1.00); }
  .text-block-3 { color: #060c21; }
  .button.is-tertiary { border-top-color: transparent; border-right-color: transparent; border-bottom-color: transparent; border-left-color: transparent; background-color: transparent; color: #060c21; }
  .text-color-graytrue500 { color: hsla(0, 0.00%, 45.10%, 1.00); }
  .text-rich-text figcaption { border-left-color: #060c21; }
  .button-2 { border-top-color: #060c21; border-right-color: #060c21; border-bottom-color: #060c21; border-left-color: #060c21; background-color: #060c21; color: hsla(0, 0.00%, 100.00%, 1.00); }
  .rl-styleguide_color.is-gray25 { background-color: #fcfcfd; }
  .background-color-gray100 { background-color: #f2f4f7; }
  .rl-styleguide_color.is-graytrue100 { background-color: hsla(0, 0.00%, 96.08%, 1.00); }
  .home_hero-header_background-image-wrapper { background-image: linear-gradient(to bottom, rgba(0,0,0,0.50),rgba(0,0,0,0.50)); }
  .the-work_additional-wrapper { color: hsla(0, 0.00%, 99.22%, 1.00); }
  .text-color-graytrue800 { color: hsla(0, 0.00%, 16.08%, 1.00); }
  .rl-styleguide_color.is-gray900 { background-color: hsla(219.99999999999997, 42.86%, 10.98%, 1.00); }
  .background-color-gray500 { background-color: hsla(220.6451612903226, 13.19%, 46.08%, 1.00); }
  body { color: #060c21; }
  .gradient { background-image: linear-gradient(to bottom, #fcfcfc 30%, #060c21 63%, #060c21 79%, hsla(0, 0.00%, 94.00%, 1.00)); }
  .rl-styleguide_color.is-graytrue500 { background-color: hsla(0, 0.00%, 45.10%, 1.00); }
  .title-company { color: #060c21; }
  .rl-styleguide-message-delete-this { background-color: hsla(40, 9.68%, 93.92%, 1.00); }
  .rl-styleguide_subheading { background-color: hsla(0, 0.00%, 82.67%, 1.00); color: #060c21; }
  .header_wrapper { color: #060c21; }
  .text-size-large.text-color-white { color: #f5f5f7; }
  .text-color-graytrue900 { color: #060c21; }
  .rl-styleguide_color.is-gray200 { background-color: hsla(219.99999999999983, 16.67%, 92.94%, 1.00); }
  .background-color-gray300 { background-color: #d0d5dd; }
  .rl-styleguide_color.is-graytrue600 { background-color: hsla(0, 0.00%, 32.16%, 1.00); }
  .heading-style-h5 { color: #060c21; }
  .text-color-white { color: #f5f5f7; }
  .form-radio-icon { border-top-color: #060c21; border-right-color: #060c21; border-bottom-color: #060c21; border-left-color: #060c21; }
  .background-color-graytrue300 { background-color: hsla(0, 0.00%, 83.92%, 1.00); }
  .text-block-2 { color: hsla(0, 0.00%, 100.00%, 1.00); }
  .home_gallery_image { border-top-color: #060c21; border-right-color: #060c21; border-bottom-color: #060c21; border-left-color: #060c21; }
  .text-color-graytrue600 { color: hsla(0, 0.00%, 32.16%, 1.00); }
  .rl-styleguide_color.is-gray50 { background-color: #f9fafb; }
  .background-color-gray800 { background-color: #1d2939; color: whitesmoke; }
  .footer.background-color-graytrue25 { background-color: #060c21; }
  .footer.background-color-graytrue900 { background-color: hsla(0, 0.00%, 100.00%, 1.00); }
  .rl-styleguide_color.is-graytrue50 { background-color: hsla(0, 0.00%, 98.04%, 1.00); }
  .background-color-white { background-color: hsla(0, 0.00%, 100.00%, 1.00); }
  .background-color-graytrue900 { background-color: #060c21; }
  .rl-styleguide_empty-box { background-color: hsla(0, 0.00%, 93.33%, 1.00); }
  .section_process { background-color: #060c21; }
  .the-pricing_subscription-card.shadow-medium { background-color: hsla(0, 0.00%, 100.00%, 1.00); }
  .rl-styleguide_label { background-color: #0073e6; color: hsla(0, 0.00%, 100.00%, 1.00); }
  .section_one-liner2 { background-color: #060c21; }
  .background-color-graytrue400 { background-color: hsla(0, 0.00%, 63.92%, 1.00); }
  .text-color-gray100 { color: #f2f4f7; }
  .background-color-gray50 { background-color: #f9fafb; }
  .line-divider { background-color: #060c21; }
  .form-checkbox-icon { border-top-color: #060c21; border-right-color: #060c21; border-bottom-color: #060c21; border-left-color: #060c21; }
  .background-color-graytrue800 { background-color: hsla(0, 0.00%, 16.08%, 1.00); }
  .heading-style-h3.text-align-center { color: hsla(0, 0.00%, 100.00%, 1.00); }
  .text-color-gray900 { color: #101828; }
  .heading-15 { color: hsla(0, 0.00%, 100.00%, 1.00); }
  .the-faqs_component { border-bottom-color: hsla(0, 0.00%, 100.00%, 1.00); }
  .loader_bottom { background-color: #e54326; }
  .rl-styleguide_spacing { border-top-color: hsla(0, 0.00%, 82.75%, 1.00); border-right-color: hsla(0, 0.00%, 82.75%, 1.00); border-bottom-color: hsla(0, 0.00%, 82.75%, 1.00); border-left-color: hsla(0, 0.00%, 82.75%, 1.00); }
  .text-color-gray50 { color: #f9fafb; }
  .background-color-gray25 { background-color: #fcfcfd; }
  .the-studio_title { color: #060c21; }
  .navbar2_component-2 { background-color: hsla(0, 0.00%, 100.00%, 1.00); }
  .text-block-4 { color: #060c21; }
  .nav-menu { background-color: hsla(0, 0.00%, 98.82%, 1.00); }
  .background-color-graytrue200 { background-color: hsla(0, 0.00%, 89.80%, 1.00); }
  .testimonial6_rating-icon { color: #060c21; }
  .text-color-gray800 { color: #1d2939; }
  .section_services { background-color: #060c21; }
  .background-color-gray600 { background-color: hsla(215.625, 18.39%, 34.12%, 1.00); }
  .section_the-faqs { background-color: transparent; }
  .padding-global { color: #060c21; }
  .text-color-gray400 { color: #98a2b3; }
  h1 { color: #060c21; }
  a { border-top-color: #060c21; border-right-color: #060c21; border-bottom-color: #060c21; border-left-color: #060c21; color: #060c21; }
  .home_latest-projects_arrow-icon { color: #060c21; }
  .the-faqs_question { border-top-color: #060c21; }
  .loader_container { background-color: #e54326; }
  .text-color-gray200 { color: #e4e7ec; }
  h2 { color: #060c21; }
  .text-style-quote { border-left-color: #060c21; }
  .testimonial-details { color: #060c21; }
  h3 { color: #060c21; }
  .pricing5_divider { background-color: #060c21; }
  .button.is-secondary { background-color: transparent; color: #060c21; }
  .loading_title { color: #f5f5f7; }
  .rl-styleguide_color.is-graytrue300 { background-color: hsla(0, 0.00%, 83.92%, 1.00); }
  .form-input.is-select-input { background-image: none; }
  h4 { color: #060c21; }
  .rl-styleguide_color.is-graytrue200 { background-color: hsla(0, 0.00%, 89.80%, 1.00); }
  .button.is-link { background-color: transparent; color: hsla(216.9230769230769, 65.55%, 46.67%, 1.00); }
  .heading-18 { color: #060c21; }
  h5 { color: #060c21; }
  .navbar2_component { border-top-color: #060c21; border-right-color: #060c21; border-bottom-color: #060c21; border-left-color: #060c21; background-color: hsla(0, 0.00%, 100.00%, 1.00); }
  .rl-styleguide_tutorial-callout { border-top-color: #060c21; border-right-color: #060c21; border-bottom-color: #060c21; border-left-color: #060c21; background-color: hsla(0, 0.00%, 100.00%, 1.00); }
  .text-block-5 { color: #060c21; }
  .loader_progress { background-color: #060c21; }
  h6 { color: #060c21; }
  blockquote { border-left-color: #060c21; }
  .rl-styleguide_callout-link-wrapper { background-image: linear-gradient(135deg, hsla(14.426229508196721, 100.00%, 64.12%, 0.15), hsla(0, 100.00%, 64.12%, 0.15) 50%, hsla(248.5245901639344, 100.00%, 64.12%, 0.15)), linear-gradient(to bottom, hsla(0, 0.00%, 100.00%, 1.00),hsla(0, 0.00%, 100.00%, 1.00)); }
  .rl-styleguide_callout-link { background-color: hsla(0, 0.00%, 100.00%, 1.00); background-image: linear-gradient(135deg, hsla(14.426229508196721, 100.00%, 64.12%, 1.00), hsla(0, 100.00%, 64.12%, 1.00) 50%, hsla(248.5245901639344, 100.00%, 64.12%, 1.00)); }
  .text-size-medium { color: #060c21; }
  .rl-styleguide_label.is-html-tag { background-color: #be4aa5; }
  .rl-styleguide_color.is-black { background-color: #060c21; color: #060c21; }
  .nav-link { color: #060c21; }
  .most-popular_tag { color: #f5f5f7; }
  .the-pricing_subscription-card { border-top-color: #060c21; border-right-color: #060c21; border-bottom-color: #060c21; border-left-color: #060c21; -webkit-text-stroke-color: #060c21; }
  .rl-styleguide_heading { background-color: #060c21; color: hsla(0, 0.00%, 100.00%, 1.00); }
  .text-style-link { color: hsla(216.9230769230769, 65.55%, 46.67%, 1.00); }
  .button.is-secondary { background-color: transparent; color: #060c21; }
  .background-color-bar { background-color: hsla(227.14285714285714, 0.00%, 100.00%, 1.00); }
  .text-color-graytrue100 { color: hsla(0, 0.00%, 96.08%, 1.00); }
  .section_highlights { background-color: #060c21; }
  .background-color-gray200 { background-color: hsla(219.99999999999983, 16.67%, 92.94%, 1.00); }
  .background-color-graytrue700 { background-color: hsla(0, 0.00%, 25.88%, 1.00); }
  .text-color-graytrue400 { color: hsla(0, 0.00%, 63.92%, 1.00); }
  .rl-styleguide_color.is-gray500 { background-color: hsla(220.6451612903226, 13.19%, 46.08%, 1.00); }
  .heading-16 { color: hsla(0, 0.00%, 100.00%, 1.00); }
  .button { border-top-color: #060c21; border-right-color: #060c21; border-bottom-color: #060c21; border-left-color: #060c21; background-color: #060c21; color: hsla(0, 0.00%, 100.00%, 1.00); }
  .text-color-black { color: #060c21; }
  .background-color-graytrue600 { background-color: hsla(0, 0.00%, 32.16%, 1.00); }
  .button.is-alternate { background-color: hsla(0, 0.00%, 100.00%, 1.00); color: #060c21; }
  .navbar1_component { border-bottom-color: #060c21; background-color: hsla(0, 0.00%, 100.00%, 1.00); }
  .home_subscription-area_divider { background-color: #060c21; }
  .text-color-graytrue700 { color: hsla(0, 0.00%, 25.88%, 1.00); }
  .rl-styleguide_color.is-gray400 { background-color: hsla(217.77777777777777, 15.08%, 64.90%, 1.00); }
  .background-color-gray700 { background-color: hsla(217.5, 23.53%, 26.67%, 1.00); }
  .text-block-6 { color: #060c21; }
  .text-size-small { color: #060c21; }
  .background-color-graytrue50 { background-color: hsla(0, 0.00%, 98.04%, 1.00); }
  .rl-styleguide-message-wrapper { background-color: hsla(35.999999999999794, 8.47%, 88.43%, 1.00); }
  .text-color-gray500 { color: #667085; }
@media screen and (max-width: 991px) {
  .menu-icon2_line-middle { background-color: #060c21; }
  .menu-icon1_line-middle { background-color: #060c21; }
  .navbar1_menu { border-bottom-color: #060c21; background-color: hsla(0, 0.00%, 100.00%, 1.00); }
  .menu-icon2_line-bottom { background-color: #060c21; }
  .menu-icon1_line-bottom { background-color: #060c21; }
  .menu-icon1_line-top { background-color: #060c21; }
  .menu-icon2_line-top { background-color: #060c21; }
  .navbar2_menu { border-bottom-color: #060c21; background-color: hsla(0, 0.00%, 100.00%, 1.00); }
}
  .navbar { background: #fcfcfc; }
  .client_logo-bar { background-color: #f5f5f5; }
  .book-call_bar:hover .cta_bar { background-color: #f0f0f0; }

/* ---- Strikethrough wordmark (v14: now only used in Yosei's testimonial,
   "working with ~~Studio~~"). The public name on preview is WJP Studio,
   set plain, no strike, in the nav and footer. ---------------------- */
.wordmark {
  text-transform: none;
  text-decoration-line: line-through;
  text-decoration-thickness: 0.08em;
  text-decoration-skip-ink: none;
  letter-spacing: -0.01em;
}
a.wordmark { color: inherit; text-decoration-color: currentColor; }
.logo_wordmark { font-size: 1.25rem; font-weight: 700; color: #060c21; text-decoration: none; white-space: nowrap; }
.footer_logo-wrapper .alt-logo-footer { font-size: 3rem; font-weight: 900; line-height: 1.1; margin: 0; }
.testimonial_wrapper .wordmark, .the-faqs_question .wordmark { font-weight: inherit; }

/* ---- Black and white only: replace the old link blue -------------- */
.text-style-link,
.button.is-link {
  color: #060c21;
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-decoration-thickness: 1px;
}
.nav-link-2 { color: #060c21; }

/* ---- Book a Call bar: ORIGINAL size + ORIGINAL slide-up interaction --
   Size is untouched styles.css: .cta_bar 12rem, .book-call-text 6rem / 900;
   tablet 10rem / 3.5rem; mobile 10rem / 3.3rem.
   Behavior (main.js initBookCallBar): off-screen below the viewport while
   the hero is on screen; slides up and stays fixed once the hero has left;
   slides away again when the hero comes back. Reduced motion: instant.   */
.book-call_bar a.cta_bar { text-decoration: none; color: inherit; }
.book-call_bar {
  transform: translate3d(0, 100%, 0);
  visibility: hidden;               /* hidden bar is not focusable or announced */
  transition: transform 0.7s var(--reveal-ease), visibility 0s linear 0.7s;
}
.book-call_bar.is-visible {
  transform: translate3d(0, 0, 0);
  visibility: visible;
  transition: transform 0.7s var(--reveal-ease), visibility 0s linear 0s;
}
@media (prefers-reduced-motion: reduce) {
  .book-call_bar, .book-call_bar.is-visible { transition: none !important; }
}

/* Hero is a clean full viewport: no space reserved for a hidden bar
   (styles.css reserved padding-bottom: var(--cta-bar-h) = 12rem).       */
.section_header { padding-bottom: 0 !important; }

/* ---- "Our approach: / remove all distraction." scroll-tied fade (v11) ---
   Rebuild of the original site feel: the heading fades in as the black
   band enters, is fully readable around the middle of the viewport, and
   fades out to gone as you keep scrolling. main.js initApproachLines sets
   the heading's opacity from its position on every scroll frame. The text
   is visible by default (no CSS opacity 0), so without JS it simply shows.
   The v4 one-shot masked slide-up was dropped because it fought the fade.
   Under prefers-reduced-motion JS does nothing and the text stays static.
   Type scale is untouched styles.css (h2, white, centered).             */
.approach_heading > div { display: block; width: 100%; height: 0; margin: 0; padding: 0; }
.approach_mask { display: block; padding-bottom: 0.06em; }
.approach_line { display: inline-block; }
.approach_heading { will-change: opacity; }
@media (prefers-reduced-motion: reduce) {
  .approach_heading { opacity: 1 !important; will-change: auto; }
}

/* ---- The Offer (black) ---------------------------------------------- */
.offer_title { margin: 0 0 1rem; text-align: left; }
.offer_intro { color: #a3a3a3; font-size: 1.5rem; font-weight: 500; line-height: 1.45; margin: 0 0 4rem; max-width: 40rem; }
.offer_intro .offer_selective { display: block; color: #fff; font-weight: 700; margin-top: 0.5rem; }
.section_services .services_grid-wrapper { align-items: stretch; bottom: 0; }
.section_services .services_grid { grid-template-columns: 1fr 1fr 1fr; row-gap: 4rem; text-align: left; }
.section_services .services_grid-item { align-items: flex-start; }
.section_services .services-size { margin: 0; line-height: 1.1; font-size: 3rem; }
.services_desc { color: #a3a3a3; font-size: 1.125rem; line-height: 1.5; margin: 0.75rem 0 0; max-width: 20rem; }
/* v16: the What we don't do block (.offer_not) and its rules were removed. */

/* ---- The How: three simple steps ------------------------------------ */
.section_the-how .more_line-space { max-width: 48rem; line-height: 1.6; }
.how_steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4rem; margin-top: 2rem; }
.how_step { border-top: 1px solid #060c21; padding-top: 1.5rem; }
.how_step-num { font-size: 1rem; font-weight: 700; margin-bottom: 1rem; }
.how_step .process-size { font-size: 2.25rem; line-height: 1.1; margin: 0 0 1rem; }
.how_step .text-size-large { line-height: 1.55; font-weight: 500; }

/* ---- FAQ close ------------------------------------------------------ */
.the-faqs_questions-still-wrapper { scroll-margin-top: 6rem; }

/* ---- Responsive ------------------------------------------------------ */
@media screen and (max-width: 991px) {
  .section_services .services_grid { grid-template-columns: 1fr 1fr; }
  .how_steps { grid-template-columns: 1fr; gap: 2.5rem; }
}
@media screen and (max-width: 767px) {
  .section_services .services_grid { grid-template-columns: 1fr; row-gap: 2.5rem; }
  .section_services .services-size { font-size: 2.25rem; }
}

/* ---- v5 hero: five stacked words (locked by Weston, Nov 9, 2026) -----
   Lead's spec for .heading-40 is clamp(2.5rem, 8vw, 6.2rem) / 900 / 1.05.
   That rule already exists in styles.css (line ~6397) but never applied:
   its selector list starts with ".Heading.40", which is invalid CSS, so the
   browser drops the whole rule and desktop fell back to 8rem / 1.2.
   Re-declared here with a valid selector, desktop only (>= 992px), so the
   spec'd scale actually renders. Tablet/mobile keep their rendered sizes.
   Only the hero's vertical padding is tightened so five lines + SRR + the
   logo bar fit a 100svh first screen. Type size is not reduced below spec. */
@media screen and (min-width: 992px) {
  .header_wrapper-update .heading-40 {
    font-size: clamp(2.5rem, 8vw, 6.2rem);
    font-weight: 900;
    line-height: 1.05;
    letter-spacing: -0.15px;
  }
  /* hero padding: see v8 below */
}

/* ---- v5 Offer: five pillars, tight one-line voice -------------------
   One short line per pillar (approved Nov 9, 2026). Layout: see v7
   below (true 3 + 2, no empty cell).                                    */
.services_grid--pillars .services_desc { font-size: 1.25rem; font-weight: 600; color: #d4d4d4; max-width: 22rem; }

/* ---- v8 hero: client logo bar pinned to the bottom of the first screen ----
   (Replaces the v6 hero padding rules.) Weston: no gap under the logo bar.
   The 12px sliver came from styles.css giving .client_logo-bar a 12px
   margin-bottom. Now:
   - .client_logo-bar: no margin or padding lifting it; margin-top: auto
     pins it to the bottom edge of the header.
   - .header_top-wrapper takes all leftover space (flex: 1 0 auto), so extra
     height goes ABOVE the logos, and the five words center in the space
     between the nav and the bar.
   - Desktop: the header is at least 100svh but may grow (height: auto) when
     the five words + nav clearance + bar can't share one screen. When they
     fit, the bar's bottom = the bottom of the screen and the SRR band starts
     exactly at the fold. When they don't (under ~752px tall, e.g. 1280x720),
     nothing overlaps and Plan. stays clear of the nav; the bar runs past
     the fold instead.
   - padding-top 6.5rem keeps the H1 line box at least 104px down (the nav is
     0 to 120 and opaque; the glyphs start about 20px into the line box).
     Type size is never reduced.                                          */
.section_header { padding-bottom: 0 !important; }
.section_header > .client_logo-bar { margin: auto 0 0 0 !important; padding-bottom: 0 !important; flex: 0 0 auto; }
.section_header > .header_top-wrapper { flex: 1 0 auto; min-height: auto; }
@media screen and (min-width: 992px) {
  .section_header { height: auto !important; min-height: 100svh !important; }
  .section_header .padding-section-large { padding-top: 6.5rem; padding-bottom: 0; }
}

/* ---- v7 Offer: true 3 + 2 grid, no empty cell -------------------------
   Desktop (>= 992px): 6-column grid. Items 1 to 3 (Plan, Design,
   Develop) span 2 columns each = three equal columns. Items 4 and 5
   (Automate, Iterate) span 3 each = two equal columns across the full
   width. Tablet (768 to 991px): 2 columns, and the fifth item (Iterate)
   spans both so no hole shows. Mobile (< 768px): one column (unchanged). */
@media screen and (min-width: 992px) {
  .section_services .services_grid--pillars { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .section_services .services_grid--pillars > .services_grid-item { grid-column: span 2; }
  .section_services .services_grid--pillars > .services_grid-item:nth-child(n+4) { grid-column: span 3; }
}
@media screen and (min-width: 768px) and (max-width: 991px) {
  .section_services .services_grid--pillars { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .section_services .services_grid--pillars > .services_grid-item:nth-child(5) { grid-column: 1 / -1; }
}

/* ---- v7 The How: display image left, steps stacked right ---------------
   Reuses the original .process_container / .process_wrapper-left /
   .process_wrapper-right / .image-3 classes; the layout is pinned here so
   the original's assorted breakpoint rules can't fight it.              */
.section_the-how .process_container { display: flex; flex-direction: row; align-items: center; justify-content: flex-start; gap: 5rem; margin-top: 1rem; }
.section_the-how .process_wrapper-left { display: flex; justify-content: center; align-self: center; width: auto; flex: 0 0 48%; }
.section_the-how .process_wrapper-right { display: flex; flex-direction: column; justify-content: center; flex: 1 1 0; min-width: 0; width: auto; }
.section_the-how .process_wrapper-right .how_steps { grid-template-columns: 1fr; gap: 2.5rem; margin-top: 0; }
.section_the-how .process_wrapper-right .how_step .process-size { font-size: 2rem; }
@media screen and (max-width: 991px) {
  .section_the-how .process_container { flex-direction: column; align-items: stretch; gap: 3rem; }
  .section_the-how .process_wrapper-left { flex: none; width: 100%; max-width: 36rem; margin: 0 auto; }
}

/* ---- v9: Subscribe. Request. Receive. band on white ---------------------
   Weston: the SRR band under the logo bar should not run back-to-back black
   with The Offer. White background, ink matching the hero words
   (.heading-40 computes to #060C22). The h3s keep their
   .text-color-white class because styles.css hangs the SRR size rules on
   .text-color-white.srr_custom (2.8rem) and .text-color-white (3rem); the
   color is overridden here, scoped to this band only, so The Offer's
   .text-color-white headings stay white.                                  */
.section_process { background-color: #ffffff; }
.section_process .text-color-white.srr_custom { color: #060c21; }

/* ---- v11 The Production: a real 2 x 2 grid of four -------------------
   styles.css gives the rows grid columns but never display: grid, and drops
   to one column under 767px. Pinned here: the component stacks the two rows,
   and each row is a 2-column grid, so the four images read as 2 x 2 on
   desktop and tablet (phones: one column, v12). Tiles stay square (styles.css padding-top: 100% wrapper with
   the image filling it); the existing hover zoom is untouched.          */
.section_the-work .the-work_gallery_component { display: grid; grid-template-columns: minmax(0, 1fr); row-gap: 2rem; column-gap: 0; }
.section_the-work .the-work_gallery_row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: auto; column-gap: 2rem; row-gap: 0; -webkit-text-stroke-width: 0; }
/* v12 (Lead, after reviewing v11): phones (< 768px) stack all four as one
   column, work-1 to work-4, because 2 x 2 tiles were too small there.
   Desktop and tablet stay 2 x 2.                                        */
@media screen and (max-width: 767px) {
  .section_the-work .the-work_gallery_component { row-gap: 1.5rem; }
  .section_the-work .the-work_gallery_row { grid-template-columns: minmax(0, 1fr); column-gap: 0; row-gap: 1.5rem; }
}

/* ---- v11 "We make complex problems simple." band, inverted --------------
   It sat on the same light gray as The How and Testimonials and vanished
   into them. Now black with the site's white (#f5f5f7, same as
   .text-color-white on the other black bands). Copy, size, tracking, and
   padding unchanged. Scoped to the section; the footer line is untouched. */
.section_one-liner3.background-color-graytrue25 { background-color: #060c21; }
.section_one-liner3 .simplicity_mobile { color: #fff; }

/* ---- v13 phone section titles: one line, period included --------------
   On phones (< 768px) the four section titles (The Offer., The
   Production., The How., The FAQs., the only .heading-style-h1 on the
   page) share one size that scales with the viewport. "The Production."
   is the longest: about 7.47em wide. Content width is about 90vw (5vw side
   padding), so 11.4vw leaves roughly 5% slack before the padding edge.
   Capped at the existing 4.5rem, floor 2rem. nowrap is safe because the
   size is computed to fit. Tablet (>= 768px) and desktop untouched.      */
@media screen and (max-width: 767px) {
  .section_the-work .heading-style-h1,
  .section_the-how .heading-style-h1,
  .section_the-faqs .heading-style-h1,
  .section_services .heading-style-h1.offer_title {
    font-size: clamp(2rem, 11.4vw, 4.5rem);
    white-space: nowrap;
  }
}

/* ---- v15 hero supporting line ------------------------------------------
   "Ongoing support for a more efficient business." directly under the five
   words, inside .header_wrapper-update. A new class on purpose: styles.css
   hides .header_wrapper-update .srr_custom until html.is-ready. This line
   has NO initial hide, so it is visible even if JS never runs. Same ink as
   .heading-40 (#060C22), clearly smaller. Space for it comes out of the
   flexible area above the logo bar (v8), never from below the bar.       */
.header_wrapper-update .hero_support-line {
  margin: 1.5rem 0 0 0;
  color: #060c21;
  font-size: 1.375rem;
  font-weight: 500;
  line-height: 1.45;
  letter-spacing: normal;
  max-width: 100%;
  opacity: 1;
}
@media screen and (max-width: 767px) {
  .header_wrapper-update .hero_support-line { margin-top: 1rem; font-size: 1.125rem; }
}
/* v15: on tablet and phone the header was a fixed 100svh with overflow
   hidden, so on very short phones (320x640) the extra line pushed the logo
   bar past the header and clipped it. Same rule as desktop v8: at least one
   screen tall, grows only when the content can't fit.                    */
@media screen and (max-width: 991px) {
  .section_header { height: auto !important; min-height: 100svh !important; }
}
/* v15: short desktop windows (< 800px tall). The five words, nav
   clearance, this line, and the bar can't share the screen, so keep the
   overrun small: tighter gap and an 18px line here. Word size untouched. */
@media screen and (min-width: 992px) and (max-height: 799px) {
  .header_wrapper-update .hero_support-line { margin-top: 0.75rem; font-size: 1.125rem; }
}

/* ---- v22 The Pricing: two monthly cards ---------------------------------
   Placed after The How (and its testimonials) and before The FAQs. Title
   uses the shared .heading-style-h1 scale; the phone clamp/nowrap rule
   from v13 is extended to it below. Cards are black with the site's white
   (#f5f5f7) on the light section, side by side from 768px up, stacked on
   phones. Everything is static and visible without JS. CTAs reuse the
   booking hook (href="#contact" data-link="booking") so initLinks binds. */
.section_pricing .heading-style-h1 { margin: 0; }
.pricing_intro { margin: 1.5rem 0 0; max-width: 40rem; color: #060c21; font-size: 1.5rem; font-weight: 500; line-height: 1.45; }
.pricing_grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2rem; margin-top: 4rem; }
.pricing_card { display: flex; flex-direction: column; background-color: #060c21; color: #f5f5f7; padding: 3rem; }
.pricing_name { margin: 0; color: #f5f5f7; font-size: 2.25rem; font-weight: 900; line-height: 1.1; }
.pricing_amount { margin: 2rem 0 0; color: #f5f5f7; font-size: 4rem; font-weight: 900; line-height: 1; letter-spacing: -0.02em; white-space: nowrap; }
.pricing_line { margin: 1rem 0 0; color: #d4d4d4; font-size: 1.25rem; font-weight: 600; line-height: 1.45; }
.pricing_card .pricing_cta { display: block; margin: 2rem 0 0; padding: 1rem 1.5rem; background-color: #f5f5f7; color: #060c21; border: 1px solid #f5f5f7; text-align: center; font-size: 1.125rem; font-weight: 700; text-decoration: none; }
.pricing_card .pricing_cta:hover { background-color: #060c21; color: #f5f5f7; }
.pricing_list { list-style: none; margin: 2.5rem 0 0; padding: 0; }
.pricing_list li { padding: 1rem 0; border-top: 1px solid #333; color: #f5f5f7; font-size: 1.125rem; font-weight: 500; line-height: 1.45; }
.pricing_note { margin: 2.5rem 0 0; color: #424242; font-size: 1rem; font-weight: 500; }
@media screen and (min-width: 768px) and (max-width: 991px) {
  .pricing_card { padding: 2rem; }
  .pricing_amount { font-size: 3rem; }
}
@media screen and (max-width: 767px) {
  .section_pricing .heading-style-h1 { font-size: clamp(2rem, 11.4vw, 4.5rem); white-space: nowrap; }
  .pricing_intro { font-size: 1.25rem; }
  .pricing_grid { grid-template-columns: minmax(0, 1fr); gap: 1.5rem; margin-top: 2.5rem; }
  .pricing_card { padding: 2rem 1.5rem; }
  .pricing_amount { font-size: 3rem; }
}

/* ---- v23 Offer: full 3 x 2 grid ------------------------------------------
   Replaces the v7 3 + 2 spans. Desktop (>= 992px): three equal columns,
   every item spans one, so Automate sits under Plan, Iterate under Design,
   and the sixth tile (.offer_start) under Develop. Tablet: two columns,
   three rows (the v7 full-width Iterate span is undone). Phone: one
   column. Source order keeps the pillars first and the tile last.       */
@media screen and (min-width: 992px) {
  .section_services .services_grid--pillars { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .section_services .services_grid--pillars > .services_grid-item,
  .section_services .services_grid--pillars > .services_grid-item:nth-child(n+4) { grid-column: auto; }
}
@media screen and (min-width: 768px) and (max-width: 991px) {
  .section_services .services_grid--pillars > .services_grid-item:nth-child(5) { grid-column: auto; }
}
/* Sixth tile: inverted (white on the black Offer), same grid cell as the
   pillars. It fills its cell (align-self: stretch) and insets its content
   so the white reads as a tile. Book a call, booking hook only.          */
.section_services .services_grid--pillars > .offer_start {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  box-sizing: border-box;
  background-color: #f5f5f7;
  color: #060c21;
  padding: 2rem;
}
.offer_start .offer_start-eyebrow { margin: 0; color: #424242; font-size: 0.875rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.offer_start .offer_start-heading { margin: 0.75rem 0 0; color: #060c21; font-size: 2.5rem; font-weight: 900; line-height: 1.05; }
.offer_start .offer_start-body { margin: 1rem 0 0; color: #262626; font-size: 1.125rem; font-weight: 600; line-height: 1.45; max-width: 22rem; }
.offer_start .offer_start-button {
  display: inline-block; margin-top: auto; padding: 0.875rem 1.75rem;
  background-color: #060c21; color: #f5f5f7; border: 1px solid #060c21; border-radius: 100px;
  font-size: 1rem; font-weight: 700; line-height: 1.2; text-decoration: none;
  transition: background-color 0.2s ease, color 0.2s ease;
}
.offer_start .offer_start-body + .offer_start-button { margin-top: 1.75rem; }
.offer_start .offer_start-button:hover { background-color: transparent; color: #060c21; }
.offer_start .offer_start-button:focus-visible { outline: 2px solid #060c21; outline-offset: 3px; }
@media screen and (max-width: 767px) {
  .section_services .services_grid--pillars > .offer_start { padding: 1.75rem 1.5rem; }
  .offer_start .offer_start-heading { font-size: 2rem; }
}

/* ---- v25 hero link ------------------------------------------------------------
   The v23 pill and the questionnaire are gone (questionnaire.js stays on
   disk, unloaded; its CSS was removed with it). One underlined text link,
   same style as the v23 "or book a call" link, centered under the line. */
.header_wrapper-update .hero_book { margin: 1.5rem 0 0; text-align: center; }
.hero_book .hero_book-link { color: #060c21; font-size: 1.0625rem; font-weight: 600; text-decoration: underline; text-underline-offset: 0.2em; }
.hero_book .hero_book-link:hover { text-decoration-thickness: 2px; }
.hero_book .hero_book-link:focus-visible { outline: 2px solid #060c21; outline-offset: 3px; }
@media screen and (max-width: 767px) {
  .header_wrapper-update .hero_book { margin-top: 1.25rem; }
  .hero_book .hero_book-link { font-size: 1rem; }
}
@media screen and (min-width: 992px) and (max-height: 799px) {
  .header_wrapper-update .hero_book { margin-top: 1rem; }
}

/* ---- v24 hero: giant wordmark -----------------------------------------------
   The name is the text of h1.hero_wordmark (one line in index.html).
   hero-motion.js fits it to the content width; the vw size here is the
   no-JS fallback sized for "WJP Studio". Black on the light hero.      */
.hero_stack { width: 100%; }
.hero_wordmark {
  width: 100%; margin: 0; color: #060c21;
  font-size: 17.4vw; font-weight: 900; line-height: 0.9; letter-spacing: -0.045em;
  white-space: nowrap;
}
.hero_wordmark-text { display: inline-block; padding-right: 0.02em; }
.hero_srr { margin: 1.5rem 0 0; color: #060c21; font-size: clamp(1.5rem, 2.9vw, 2.75rem); font-weight: 800; line-height: 1.1; letter-spacing: -0.01em; }
.header_wrapper-update.hero_stack .hero_support-line { margin-top: 1rem; }
@media screen and (max-width: 767px) {
  .hero_srr { margin-top: 1rem; font-size: 1.5rem; }
  .header_wrapper-update.hero_stack .hero_support-line { margin-top: 0.75rem; }
}
@media screen and (min-width: 992px) and (max-height: 799px) {
  .hero_srr { margin-top: 1rem; }
  .header_wrapper-update.hero_stack .hero_support-line { margin-top: 0.75rem; }
}

/* ---- v24 nav ------------------------------------------------------------------
   Conflict fix: styles.css hides .navbar (opacity 0, translateY 28px)
   until main.js adds html.is-ready. That left the nav invisible without
   JS and its transform would fight the fixed docked nav, so the load-in
   is switched off for the nav only.
   No JS: the original absolute nav at the top with the small logo.
   With JS (html.hm-js): fixed nav. v34.1: the whole nav is hidden during
   the hero and fades in as one unit after it (see the v34.1 nav block); the
   glass layer (::before) and the logo are always at full opacity inside it. */
.navbar, html.is-ready .navbar { opacity: 1; transform: none; transition: none; border-radius: 0; }
html.hm-js .navbar { position: fixed; top: 0; left: 0; right: 0; z-index: 4500; background-color: transparent; }
html.hm-js .navbar .nav-menu { background-color: transparent; }
html.hm-js .navbar::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-color: #fff; box-shadow: none;
  opacity: 1;
}
html.hm-js .navbar > * { position: relative; }
html.hm-js .navbar .logo_wordmark { opacity: 1; }

/* ---- v24 the five words: one lights up at a time -------------------------
   Placed under the logo bar, before The Offer. Default (no JS, reduced
   motion): a normal section, all five words in full ink with their lines.
   With JS and motion: a tall track (one step per word) with a sticky
   screen; inactive rows sit at low opacity (reads as light gray), the
   active row is full ink. Opacity only.                                 */
.section_words { background-color: #fff; color: #060c21; }
.words_sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.words_sticky { padding: 7rem 0; }
.words_list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.25rem; }
.words_item { display: grid; grid-template-columns: minmax(0, 0.55fr) minmax(0, 0.45fr); align-items: baseline; column-gap: 3rem; }
.words_word { font-size: clamp(3rem, min(7vw, 10.5vh), 6.2rem); font-weight: 900; line-height: 1.05; letter-spacing: -0.02em; color: #060c21; white-space: nowrap; }
/* v32: no pin, no wheel. html.hm-words (JS on, motion allowed): every word
   is light grey and the one nearest the viewport middle (IntersectionObserver
   in hero-motion.js) is ink, 250ms opacity. No JS / reduced motion: all ink. */
html.hm-words .words_word { opacity: 0.16; transition: opacity 0.25s ease-out; }
html.hm-words .words_item.is-active .words_word { opacity: 1; }
@media screen and (max-width: 767px) {
  .words_sticky { padding: 4rem 0; }
  .words_list { gap: 0.75rem; }
  .words_item { grid-template-columns: minmax(0, 1fr); row-gap: 0.125rem; }
  .words_word { font-size: clamp(2rem, 11.4vw, 4.5rem); }
}
@media screen and (max-width: 767px) and (max-height: 700px) {
  .words_list { gap: 0.5rem; }
  .words_word { font-size: clamp(2rem, 10vw, 4.5rem); }
}
/* Conflict fix: styles.css sets overflow: hidden on .page-wrapper and
   .main-wrapper, which turns them into scroll containers and stops
   position: sticky from working. overflow-x: clip keeps the same
   horizontal clipping (the logo marquee) without that side effect.     */
.page-wrapper, .main-wrapper { overflow: visible; overflow-x: clip; }
/* body is system-ui in styles.css; components opt into Figtree one by one. */
.section_words { font-family: Figtree, system-ui, sans-serif; }
.words_list > .words_item { margin: 0; padding-left: 0; }

/* ---- v25 hero: everything centered ----------------------------------------
   Wordmark, Subscribe. Request. Receive., support line, and Book a call
   are centered on every width. hero-motion.js measures the wordmark where
   it actually sits, so the morph starts from the centered spot and still
   lands on the top-left nav logo.                                        */
.header_wrapper-update.hero_stack { align-items: center; text-align: center; padding-left: 0; padding-right: 0; }
.hero_stack .hero_wordmark { text-align: center; }
.hero_stack .hero_wordmark-text { padding-right: 0; }
.hero_stack .hero_srr, .hero_stack .hero_support-line, .hero_stack .hero_book { text-align: center; margin-left: auto; margin-right: auto; }

/* ---- v26 hero: the screen from assets/the-how-display.webp -----------------
   Measured from the monitor image: the name spans 50% of the screen width,
   centered; Subscribe. Request. Receive. spans about 30%, sits about 2.4%
   of the width below the name, and is small and bold; nothing else is in
   the hero. Fixed proportion (no fit-to-width): the name is sized so its
   width is about 50vw (about 76vw on phones). Same weight and the same
   letter-spacing (--wm-ls) as the nav logo, so the morph lands exactly. */
:root { --wm-ls: 0.015em; }
.hero_stack .hero_wordmark {
  color: #060c21; font-weight: 700; letter-spacing: var(--wm-ls); line-height: 1;
  font-size: clamp(3rem, calc(50vw / var(--wm-em, 5.66)), 15rem);
}
.hero_stack .hero_wordmark-text { padding: 0; }
.hero_stack .hero_srr {
  margin-top: clamp(1.25rem, 2.6vw, 2.75rem);
  font-size: clamp(1.125rem, 2.27vw, 2.25rem); font-weight: 800; letter-spacing: 0; line-height: 1.15; color: #060c21;
}
.logo_wordmark { font-weight: 700; letter-spacing: var(--wm-ls); }
@media screen and (max-width: 767px) {
  .hero_stack .hero_wordmark { font-size: calc(76vw / var(--wm-em, 5.66)); }
  .hero_stack .hero_srr { margin-top: 1.25rem; font-size: clamp(0.9375rem, 4.4vw, 1.125rem); }
}

/* ---- v26 tagline under the logo bar ----------------------------------------- */
.section_tagline { background-color: #fff; font-family: Figtree, system-ui, sans-serif; }
.section_tagline .tagline_text {
  margin: 0 auto; padding: 5.5rem 0; max-width: 56rem; text-align: center; text-wrap: balance;
  color: #060c21; font-size: clamp(1.25rem, 1.9vw, 1.75rem); font-weight: 500; line-height: 1.4;
}
@media screen and (max-width: 767px) {
  .section_tagline .tagline_text { padding: 3.5rem 0; font-size: 1.25rem; }
}

/* ---- v26 nav glass (v34.1: one fixed style, matched to the Book a Call bar) ---
   The ::before layer is the same glass as the Book a Call bar: white at
   var(--glass-a) (0.85; v34.1 raised from the bar's 0.72 for both, because
   0.72 over black reads as a muddy mid grey, #b8b8b8), saturate(180%)
   blur(20px), square corners, ink (#000)
   text. No stroke (v33). It never changes with the section underneath.
   Fallback without backdrop-filter: the bar's solid rgba(252,252,252,0.97).
   No JS: the static nav gets the same glass.                            */
:root { --glass-a: 0.85; }
html.hm-js .navbar::before {
  background-color: rgba(255, 255, 255, var(--glass-a));
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  box-shadow: none;
}
html:not(.hm-js) .navbar {
  background-color: rgba(255, 255, 255, var(--glass-a));
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  box-shadow: none;
}
html:not(.hm-js) .navbar .nav-menu { background-color: transparent; }
.navbar .logo_wordmark, .navbar .nav-link-2 { color: #060c21; }
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  html.hm-js .navbar::before, html:not(.hm-js) .navbar { background-color: rgba(252, 252, 252, 0.97); }
}

/* ---- v27 hero name weight --------------------------------------------------
   Matched to the monitor image's stroke weight: Figtree 900 (loaded by the
   Google Fonts import in styles.css, weights 300 to 900). Stem widths are
   within about 5% of the image at 900 (about 25% thinner at 700). The
   nav logo uses the same weight and --wm-ls so the morph lands exactly.
   --wm-em re-measured for 900 so the name stays 50vw.                    */
:root { --wm-em: 5.66; }
.hero_stack .hero_wordmark, .logo_wordmark { font-weight: 900; }

/* ---- v27 adaptive glass: removed in v34.1 -------------------------------------
   The nav no longer switches between light and dark glass. It has one fixed
   style over every section (see the v26 block and the v34.1 nav block).  */

/* ---- v27 hero scale (Weston): bigger and heavier than v26 -----------------
   Name about 62vw at 1440 (84vw on phones), Figtree 900 (the heaviest
   weight the import loads), 0.015em spacing kept. Subscribe. Request.
   Receive. scaled up with it and set at 900.                            */
.hero_stack .hero_wordmark { font-size: clamp(3rem, calc(62vw / var(--wm-em, 5.66)), 17rem); }
.hero_stack .hero_srr { margin-top: clamp(1.25rem, 3vw, 3.25rem); font-size: clamp(1.25rem, 2.8vw, 2.75rem); font-weight: 900; }
@media screen and (max-width: 767px) {
  .hero_stack .hero_wordmark { font-size: calc(84vw / var(--wm-em, 5.66)); }
  .hero_stack .hero_srr { margin-top: 1.25rem; font-size: clamp(1rem, 4.9vw, 1.25rem); }
}

/* ---- v27 tagline band: black, white, section-title weight ------------------ */
.section_tagline { background-color: #060c21; }
.section_tagline .tagline_text {
  max-width: 20ch; padding: 9rem 0; color: #fff;
  font-size: clamp(2.5rem, 5.4vw, 5.5rem); font-weight: 900; line-height: 1.05; letter-spacing: -0.01em;
  white-space: normal; text-wrap: balance;
}
@media screen and (max-width: 767px) {
  .section_tagline .tagline_text { max-width: none; padding: 5.5rem 0; font-size: clamp(2rem, 11.4vw, 4.5rem); white-space: normal; }
}

/* ---- v28 ------------------------------------------------------------------- */
/* Hero: Subscribe. Request. Receive. fades out on scroll. hero-motion.js sets
   opacity and transform inline (0 well before the name docks). No JS and
   reduced motion: nothing is set, so it stays put.                         */
html.hm-js:not(.hm-reduce) .hero_stack .hero_srr { will-change: opacity; }

/* Client logo bar: Weston's Self-Portrait, 2025 (images/weston-portrait-v28.png)
   replaces the old WJP.svg. Same img class, so the styles.css 25% / 30% width
   and auto height still apply; transparent PNG, ink hair to match the bar.  */

/* Tagline band: lighter weight (900 -> 600), more room top/bottom and at the sides.     */
.section_tagline .tagline_text {
  max-width: 24ch; box-sizing: border-box;
  padding: 12rem clamp(1.5rem, 4vw, 4rem);
  font-weight: 600; line-height: 1.1;
}
@media screen and (max-width: 767px) {
  .section_tagline .tagline_text { max-width: none; padding: 8rem 1.25rem; font-weight: 600; }
}

/* Offer: Book a call tile as frosted glass on the black Offer. Rounded,
   hairline, white text, white pill button (black text) for AA contrast.
   Fallback without backdrop-filter: a solid near-black panel.            */
.section_services .services_grid--pillars > .offer_start {
  background-color: rgba(255, 255, 255, 0.1);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 20px;
  color: #fff;
}
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .section_services .services_grid--pillars > .offer_start { background-color: #060c21; }
}
.offer_start .offer_start-eyebrow { color: rgba(255, 255, 255, 0.72); }
.offer_start .offer_start-heading { color: #fff; }
.offer_start .offer_start-body { color: rgba(255, 255, 255, 0.86); }
.offer_start .offer_start-button { background-color: #fff; color: #060c21; border-color: #fff; }
.offer_start .offer_start-button:hover { background-color: transparent; color: #fff; border-color: #fff; }
.offer_start .offer_start-button:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

/* Book a Call bar (slides up after The Offer): translucent glass to match
   the nav. It stays docked full width at the bottom (it does not float), so
   no rounded corners, just a hairline along its top edge. The light glass is
   kept dense (v34.1: var(--glass-a), 0.85, shared with the nav; was 0.72)
   so the black "Book a Call." reads over light and dark sections alike
   (over pure black the panel works out to about #d9d9d9). Fallback: solid
   near-white.                                                           */
.book-call_bar .cta_bar {
  background-color: rgba(255, 255, 255, var(--glass-a, 0.85));
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-top: 1px solid rgba(6, 12, 33, 0.08);
  color: #060c21;
}
.book-call_bar:hover .cta_bar { background-color: rgba(255, 255, 255, 0.94); }
.book-call_bar .cta_bar:focus-visible { outline: 2px solid #060c21; outline-offset: -4px; }
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .book-call_bar .cta_bar { background-color: rgba(252, 252, 252, 0.97); }
  .book-call_bar:hover .cta_bar { background-color: #f0f0f0; }
}

/* ---- v29 Offer: Book a call tile, no eyebrow, heading on the row line -----
   The eyebrow markup is gone. The heading now uses the exact pillar heading
   metrics (Figtree 900, 3rem / 1.1, 2.25rem on phones, no top margin). From
   768px up the tile is pulled up by its top padding plus its 1px border, so
   the heading's top and baseline sit on the same line as Automate. and
   Iterate. while the glass extends above it. Glass, corners, body text and
   button are unchanged. Phones: no shift, the tile stacks with its normal
   row gap.                                                                */
.offer_start .offer_start-heading { margin-top: 0; font-size: 3rem; line-height: 1.1; font-weight: 900; letter-spacing: normal; }
@media screen and (min-width: 768px) {
  .section_services .services_grid--pillars > .offer_start { margin-top: calc(-2rem - 1px); }
}
@media screen and (max-width: 767px) {
  .offer_start .offer_start-heading { font-size: 2.25rem; }
}

/* ---- v29 curtain rise -------------------------------------------------------
   hero-motion.js writes --cv-* variables on .hero_curtain from p = scrollY /
   viewport height (see the header comment there). html.hm-cv = JS is on;
   (v32: the band rise is gone; see the v32 hero pin block at the end.)
   No JS: none of this applies.                                          */
.hero_shade { display: none; }
/* v34: opacity only; the big name fades with the subline (no morph) */
html.hm-cv .hero_stack .hero_wordmark { opacity: var(--cv-name-o, 1); will-change: opacity; }
html.hm-cv .hero_stack .hero_srr { opacity: var(--cv-srr-o, 1); will-change: opacity; }
html.hm-cv.hm-logos-ready .section_header > .client_logo-bar { animation: none; opacity: var(--cv-logos-o, 1); }
html.hm-cv .client_logo-bar.is-cv-hidden .container_logos { animation-play-state: paused; }
html.hm-cv .section_tagline .tagline_text { opacity: var(--cv-tag-o, 1); transform: translate3d(0, var(--cv-tag-y, 0px), 0); }

/* ---- v29 load guard (v34: the dock handoff itself is gone) -----------------
   html.hm-pre is set by a tiny inline head script and removed by
   hero-motion.js once it runs, so the nav logo never flashes on load next to
   the hero name.                                                          */
html.hm-pre .navbar .logo_wordmark { opacity: 0; }

/* Pricing: department framing above the request line. */
.pricing_team { margin: 1rem 0 0; color: #f5f5f7; font-size: 1.25rem; font-weight: 600; line-height: 1.45; }
.pricing_team strong { font-weight: 900; }
.pricing_team + .pricing_line { margin-top: 0.25rem; }

/* FAQ: the six capability one-liners inside "What kinds of problems". */
.faq_caps { list-style: none; margin: -1rem 0 2rem; padding: 0; display: grid; gap: 0.625rem; }
.faq_caps li { margin: 0; color: #060c21; font-size: 1.2rem; line-height: 1.45; }

/* ---- v31 early black (Weston) -----------------------------------------------
   The hero shade now runs from the first scroll (p 0 to 0.30) on every width,
   and under reduced motion too (opacity only). It sits above the logo bar
   (which darkens with it, so no light seam) but under the hero name and
   subline. v34.1: the shade runs p 0.015 to 0.33; the name and subline stay
   ink and fade out (p 0 to 0.0525) while it is still light (see
   hero-motion.js).                                */
html.hm-cv .hero_shade {
  display: block; position: absolute; inset: 0; z-index: 3;
  background-color: #060c21; opacity: var(--cv-shade, 0); pointer-events: none;
}
html.hm-cv .section_header > .header_top-wrapper { position: relative; z-index: 4; }
/* v34: the name and subline both stay ink; they are gone before the shade
   gets dark, so neither ever flips to white. */
html.hm-cv .hero_stack .hero_wordmark,
html.hm-cv .hero_stack .hero_srr { color: #060c21; transition: none; }

/* ---- v32 five words: plain stacked list -------------------------------------
   Normal page flow, Figtree 900 at the existing scale, left aligned, no
   description lines. See the hm-words rules in the v24 block above.      */
.section_words .words_item { display: block; }
.section_words .words_list { gap: 0.25rem; }

/* ---- v32 hero pin (Weston) ------------------------------------------------------
   html.hm-pin = JS on, motion allowed, >= 768px. .hero_curtain is the track:
   the header (100% of its normal height, --hero-h) and the tagline section
   both stick at top 0, the tagline laid exactly over the header with a
   negative margin, and .hero_pin adds 52.5vh of scroll for the pin
   (v34.1; v33 was 35vh, before that 75vh). Inside the pin hero-motion.js scrubs, by p = scrollY /
   viewport height:
     v34.1 (v34 times 1.5, pin 52.5vh): name, subline (ink) and logo bar
     out 0 to 0.0525, background to black 0.015 to 0.33 (eased), nav dark
     glass at shade 0.5 (about 0.108), nav logo in 0.06 to 0.525, tagline
     in 0 to 0.525 (eased out)
   No hold (v33): the pin releases at 0.525, the moment the tagline and the
   nav logo are full, and the black hero scrolls away as one piece.
   Phones, reduced motion and no JS: no pin; the tagline stays its own black
   band in flow under the hero (phones fade it in as it enters).          */
.hero_pin { display: none; }
html.hm-pin .hero_curtain > .section_header { position: sticky; top: 0; z-index: 0; }
html.hm-pin .hero_curtain > .section_tagline {
  position: sticky; top: 0; z-index: 1;
  height: var(--hero-h, 100vh); margin-top: calc(-1 * var(--hero-h, 100vh));
  display: flex; align-items: center; justify-content: center;
  background-color: transparent; pointer-events: none;
}
html.hm-pin .hero_curtain > .section_tagline > .padding-global { width: 100%; height: auto; min-height: 0; align-self: center; }
html.hm-pin .section_tagline .tagline_text { padding-top: 0; padding-bottom: 0; will-change: opacity, transform; }
html.hm-pin .hero_pin { display: block; height: var(--pin-h, 52.5vh); }

/* ---- v33 no nav stroke (Weston) ---------------------------------------------
   The sticky nav has no bottom border, hairline or shadow line in any state,
   including the no-JS static nav. The nav has no Book a call button (only
   the Client login link). v34.1: there is only one nav style now.        */
.navbar, html .navbar::before, html .navbar::after,
html.hm-js .navbar::before, html:not(.hm-js) .navbar {
  border: 0; box-shadow: none; outline: 0;
}

/* ---- v34 tagline line-height (Weston) ----------------------------------------
   About 0.1 more than before (1.1 -> 1.2), on desktop (inside the pinned hero)
   and on phones (the black band under the hero). Same size and weight.   */
.section_tagline .tagline_text { line-height: 1.2; }

/* ---- v34 pricing: Standard and Pro side by side, Ultra full width -----------
   Same card markup and styles. The grid stays two columns from 768px up
   (stacked on phones, unchanged rule). .pricing_card--ultra spans both
   columns. From 992px up its content runs horizontally with grid areas:
   name and focus on the left, the request line and the included list in the
   middle, price and Book a call on the right. Below 992px it stacks like the
   other cards.                                                           */
.pricing_grid > .pricing_card--ultra { grid-column: 1 / -1; }
@media screen and (min-width: 992px) {
  .pricing_card--ultra {
    display: grid; column-gap: clamp(2rem, 4vw, 4rem); align-items: start;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr) auto;
    grid-template-areas: "name line amount" "team list cta" ". list .";
  }
  .pricing_card--ultra > .pricing_name { grid-area: name; }
  .pricing_card--ultra > .pricing_team { grid-area: team; margin-top: 1rem; }
  .pricing_card--ultra > .pricing_line { grid-area: line; margin-top: 0; align-self: end; }
  .pricing_card--ultra > .pricing_list { grid-area: list; margin-top: 1rem; }
  .pricing_card--ultra > .pricing_amount { grid-area: amount; margin-top: 0; text-align: right; }
  .pricing_card--ultra > .pricing_cta { grid-area: cta; margin-top: 1.25rem; min-width: 14rem; }
}

/* ---- v34 The How: no divider strokes between steps -------------------------
   The 1px line above 01, 02 and 03 is gone. The padding-top and the grid
   gap stay, so the three steps still read as separate.                  */
.how_step, .section_the-how .how_step { border-top: 0; }
.how_step::before, .how_step::after { content: none; }

/* ---- v35 statement slides: one shared style -----------------------------------
   "Our approach: remove all distraction." and "Hand it over. Get back to
   work." share .statement_type: Figtree 900, tight leading, white, centered,
   one fluid clamp size. Each phrase is its own block line on desktop; on
   narrow screens the lines wrap, balanced, so both fit at 320 with no
   overflow. (Supersedes the v34 statement_head size and the retired
   supporting line.)                                                     */
.one-liner_wrapper h2.statement_type {
  margin: 0 auto; max-width: none;
  font-family: Figtree, system-ui, sans-serif; font-weight: 900;
  font-size: clamp(2.5rem, 5.6vw + 1.25rem, 6rem); line-height: 1; letter-spacing: -0.025em;
  color: #fff; text-align: center; text-wrap: balance;
}
.one-liner_wrapper h2.statement_type .statement_line,
.one-liner_wrapper h2.statement_type .approach_mask { display: block; white-space: normal; padding-bottom: 0.04em; }
.one-liner_wrapper h2.statement_type .approach_line { display: inline; }
.one-liner_wrapper h2.statement_type > div { display: none; }

/* ---- v35 nav entrance (Weston; supersedes the v34.1 hidden nav) ---------------
   Client login is one element that is always there: at load it sits on its
   own at the top right of the hero (quiet, navy, white over the dark hero
   and the navy tagline band), it stays in the tab order, and later it is
   simply inside the nav once the bar fades in around it. There is never a
   second Client login. The bar's glass (::before) and the small logo are
   driven by --nav-o (0 to 1) from hero-motion.js: 0 for the whole pin and
   until the navy tagline band's bottom edge has passed the nav's top
   edge (the band has fully left the nav area), then 0 to 1 over the next 180px of scroll, and back down when you
   scroll back. The glass fades by its background alpha and blur radius
   (not by element opacity), and while --nav-o is 0 (.is-off) it has no
   background and backdrop-filter: none, so nothing blurred is painted.
   The logo is visibility hidden while off, so it is out of the tab order.
   html.hm-pre (inline head script) keeps the glass and logo off until the
   script runs. No JS: the static nav with its glass, logo and link.     */
html.hm-js .navbar { opacity: 1; visibility: visible; pointer-events: none; transition: none; }
html.hm-js .navbar .nav-link-2 { pointer-events: auto; transition: color 0.2s ease, opacity 0.2s ease; }
html.hm-js .navbar::before {
  background-color: rgba(255, 255, 255, calc(var(--glass-a) * var(--nav-o, 0)));
  -webkit-backdrop-filter: saturate(calc(100% + 80% * var(--nav-o, 0))) blur(calc(20px * var(--nav-o, 0)));
  backdrop-filter: saturate(calc(100% + 80% * var(--nav-o, 0))) blur(calc(20px * var(--nav-o, 0)));
}
html.hm-pre .navbar::before,
html.hm-js .navbar.is-off::before { background-color: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; }
html.hm-js .navbar .logo_wordmark { opacity: var(--nav-o, 0); }
html.hm-pre .navbar .logo_wordmark,
html.hm-js .navbar.is-off .logo_wordmark { opacity: 0; visibility: hidden; }
html.hm-js .navbar.is-on .logo_wordmark { pointer-events: auto; }
/* Client login over the dark hero or the black tagline band, before the bar
   is in: white. Over light (or once the glass is half in): navy.        */
html.hm-js .navbar.is-link-dark .nav-link-2 { color: #fff; }
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  html.hm-js .navbar::before { background-color: rgba(252, 252, 252, calc(0.97 * var(--nav-o, 0))); }
}

/* ---- v34.1 "Our approach: remove all distraction." exit fade -------------------
   hero-motion.js fades the heading's wrapper (opacity only, no pin) from 1,
   while the heading's center is at or below the viewport middle (or, if the
   band is shorter than the viewport, until its bottom edge comes into
   view), to 0 by the time its center is 27.5% from the top. main.js still writes the v11
   symmetric fade on the heading itself; it is held at 1 here so only the
   v34.1 fade shows. Reduced motion: no fade. No JS: full opacity.        */
html.hm-js .approach_heading { opacity: 1 !important; will-change: auto; }
html.hm-js .section_one-liner2 .one-liner_wrapper { will-change: opacity; }
@media (prefers-reduced-motion: reduce) {
  html.hm-js .section_one-liner2 .one-liner_wrapper { opacity: 1 !important; will-change: auto; }
}

/* ---- v34.1 pricing amounts (Weston's prices: $5,995, $9,995, $13,995) ---------
   "$13,995/mo" is one character wider than the old amounts; on the smallest
   phones the amount scales with the viewport so it stays on one line inside
   the card's padding (48px from 370px up, about 41.6px at 320).          */
@media screen and (max-width: 479px) {
  .pricing_card .pricing_amount { font-size: clamp(2.25rem, 13vw, 3rem); white-space: nowrap; }
}

html { color: #060c21; }

/* ---- v35 The How: text left, image right, a connecting line with a dot ---------
   index.html now puts the steps (.process_wrapper-right) before the image
   (.process_wrapper-left), so on desktop the text is on the left and the
   image on the right, and on phones the text comes first. A 1px low-contrast
   navy line runs down the left of the step text. Each step has a small
   static dot on the line (shown on its own for no JS and reduced motion).
   With JS and motion, the static dots are faint rings and one solid dot
   (.how_track-dot) travels down the line as you scroll through the steps
   (hero-motion.js sets --how-y). No horizontal dividers.                 */
.section_the-how .how_steps { position: relative; padding-left: 2.25rem; }
.section_the-how .how_steps::before {
  content: ""; position: absolute; left: 0.25rem; top: 2.25rem; bottom: 0; width: 1px;
  background-color: rgba(6, 12, 33, 0.14); pointer-events: none;
}
.section_the-how .how_step { position: relative; }
.section_the-how .how_step-dot {
  position: absolute; left: calc(-2.25rem + 0.25rem - 4px); top: calc(2.25rem - 4px);
  width: 9px; height: 9px; border-radius: 50%; background-color: #060c21; box-sizing: border-box;
}
.section_the-how .how_track-dot { display: none; }
html.hm-howdot .section_the-how .how_step-dot { background-color: #fcfcfc; border: 1px solid rgba(6, 12, 33, 0.28); }
html.hm-howdot .section_the-how .how_track-dot {
  display: block; position: absolute; z-index: 1; left: calc(0.25rem - 4.5px); top: 0;
  width: 10px; height: 10px; border-radius: 50%; background-color: #060c21;
  transform: translate3d(0, calc(var(--how-y, 2.25rem) - 5px), 0); will-change: transform; pointer-events: none;
}
@media screen and (min-width: 992px) {
  .section_the-how .process_wrapper-right { flex: 1 1 0; }
  .section_the-how .process_wrapper-left { flex: 0 0 44%; }
}

/* ---- v35 section colours ------------------------------------------------------
   Top to bottom: hero and tagline band (pinned, photo into navy), Pillars
   white, Offer navy, Work #fcfcfc, approach statement navy, How #fcfcfc,
   Pricing #f5f5f7 (was #fcfcfc, the same as How above it), statement navy,
   Testimonials white, FAQ #f5f5f7 (ends with the old footer content).  */
.section_pricing.background-color-graytrue25 { background-color: #f5f5f7; }
.section_testimonials.background-color-graytrue25 { background-color: #fff; }
.section_the-faqs.background-color-graytrue25 { background-color: #f5f5f7; }

/* ---- v35 FAQ end (was the footer) ---------------------------------------------
   Centered under the last question: a smaller WJP Studio name in navy,
   the line and the copyright in muted grey (#5f6068, 5.6:1 on #f5f5f7).
   (v35.20: the call-bar spacer is removed; see below.)                  */
.section_the-faqs .faq_end {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  margin-top: clamp(4rem, 8vw, 7rem); scroll-margin-top: 6rem;
}
.section_the-faqs .faq_end p { margin: 0; font-family: Figtree, system-ui, sans-serif; }
.section_the-faqs .faq_end-name { font-size: clamp(1.5rem, 2.4vw, 1.875rem); font-weight: 900; line-height: 1.1; letter-spacing: -0.02em; color: #060c21; }
.section_the-faqs .faq_end-line { margin-top: 0.5rem !important; font-size: 1rem; font-weight: 500; line-height: 1.4; color: #5f6068; }
.section_the-faqs .faq_end-credit { margin-top: 1.5rem !important; font-size: 0.875rem; font-weight: 400; line-height: 1.4; color: #5f6068; }
/* v35.20 (Weston): the call-bar spacer is gone (the bar now slides away
   once this footer is in view), and the FAQ keeps the shared section
   bottom padding (.padding-section-large, 10rem / 8rem / 6rem by width),
   like the other sections, instead of 0 plus the spacer. */
.section_the-faqs .footer_bottom-space-for-call-bar { display: none; height: 0; }

/* ---- v35 dark mode (Weston) ---------------------------------------------------
   html[data-theme="dark"], set by the inline head script before first paint
   from localStorage "altsupport-theme" (light by default; the system
   preference is ignored). Palette from the PN dark mode (ink only, grays
   and white where needed; /workspace/ci-linux/interface/design.md, Dark
   mode): page navy #060c21, deeper navy #030713 for the sections that are
   navy in light mode (so neighbours stay distinct), Pricing a lift
   #0e1328, the FAQ end a lighter navy #171d31, text #f2f3f7, secondary
   #a3a8b8. Monochrome logos use the PN glyph filter brightness(0)
   invert(0.95). The nav and the Book a Call bar share one dark glass,
   rgba(6, 12, 33, var(--glass-a)), with no per-section switching.     */
html[data-theme="dark"] { color-scheme: dark; color: #f2f3f7; background-color: #060c21; }
html[data-theme="dark"] body { background-color: #060c21; color: #f2f3f7; }

/* Light sections become navy; their text inverts. */
html[data-theme="dark"] .section_header,
html[data-theme="dark"] .section_words,
html[data-theme="dark"] .section_the-work.background-color-graytrue25,
html[data-theme="dark"] .section_the-how.background-color-graytrue25,
html[data-theme="dark"] .section_testimonials.background-color-graytrue25 { background-color: #060c21; }
html[data-theme="dark"] .section_pricing.background-color-graytrue25 { background-color: #0e1328; }
html[data-theme="dark"] .section_the-faqs.background-color-graytrue25 { background-color: #171d31; }
/* Navy sections go a little deeper. */
html[data-theme="dark"] .section_services,
html[data-theme="dark"] .section_one-liner2,
html[data-theme="dark"] .section_one-liner3.background-color-graytrue25,
html[data-theme="dark"] .section_tagline { background-color: #030713; }
html[data-theme="dark"] .hero_shade { background-color: #030713; }
html.hm-pin[data-theme="dark"] .hero_curtain > .section_tagline { background-color: transparent; }

html[data-theme="dark"] :is(.section_header, .section_words, .section_the-work, .section_the-how, .section_pricing, .section_testimonials, .section_the-faqs) :is(h1, h2, h3, h4, h5, h6, p, li, strong, span, div, a) { color: #f2f3f7; }
html[data-theme="dark"] .section_the-how .how_step-num,
html[data-theme="dark"] .section_the-faqs .faq_end-line,
html[data-theme="dark"] .section_the-faqs .faq_end-credit,
html[data-theme="dark"] .section_testimonials .testimonial-details.text-color-graytrue600 { color: #a3a8b8; }
html[data-theme="dark"] .section_pricing .pricing_line { color: #c4c7d0; }

/* Five words: the inactive words stay dim, the middle word is light. */
html[data-theme="dark"] .section_words .words_word { color: #f2f3f7; }

/* Hero: navy, light name and line, the logo bar a lift. */
html[data-theme="dark"] .section_header > .client_logo-bar { background-color: #0e1328; }
html[data-theme="dark"] .logos_image:not(.wjp_logo-custom),
html[data-theme="dark"] .section_testimonials img.image { filter: brightness(0) invert(0.95); }

/* Pricing: the cards were navy on light; now a lighter navy on the lift. */
html[data-theme="dark"] .section_pricing .pricing_card { background-color: #171d31; }
html[data-theme="dark"] .section_pricing .pricing_card :is(h3, div, strong, p, li, span) { color: #f2f3f7; }
html[data-theme="dark"] .section_pricing .pricing_card .pricing_line { color: #c4c7d0; }
html[data-theme="dark"] .section_pricing .pricing_card li { border-top-color: #2c3349; }
html[data-theme="dark"] .section_pricing .pricing_note { color: #a3a8b8; }
html[data-theme="dark"] .section_pricing a.button.pricing_cta { background-color: #f2f3f7; border-color: #f2f3f7; color: #060c21; }

/* Offer: the Book a call button keeps white with ink text. */
html[data-theme="dark"] .section_services a.offer_start-button { color: #060c21; }

/* Work: the photo mats lift off the navy. */
html[data-theme="dark"] .home_gallery_image { border-color: #171d31; }

/* How: the line and dots invert. */
html[data-theme="dark"] .section_the-how .how_steps::before { background-color: rgba(242, 243, 247, 0.16); }
html[data-theme="dark"] .section_the-how .how_step-dot { background-color: #f2f3f7; }
html[data-theme="dark"].hm-howdot .section_the-how .how_step-dot { background-color: #060c21; border-color: rgba(242, 243, 247, 0.34); }
html[data-theme="dark"].hm-howdot .section_the-how .how_track-dot { background-color: #f2f3f7; }

/* FAQ icons. */
html[data-theme="dark"] .section_the-faqs svg path { fill: #f2f3f7; }
html[data-theme="dark"] .section_the-faqs .the-faqs_component_accordion { border-color: #2c3349; }

/* Links and focus rings. */
html[data-theme="dark"] a:focus-visible, html[data-theme="dark"] button:focus-visible, html[data-theme="dark"] [tabindex]:focus-visible { outline-color: #f2f3f7; }

/* One dark glass for the nav and the Book a Call bar. */
html[data-theme="dark"] .navbar .logo_wordmark,
html[data-theme="dark"] .navbar .nav-link-2,
html[data-theme="dark"] .navbar.is-link-dark .nav-link-2 { color: #f2f3f7; }
html[data-theme="dark"].hm-js .navbar::before { background-color: rgba(6, 12, 33, calc(var(--glass-a) * var(--nav-o, 0))); }
html[data-theme="dark"].hm-pre .navbar::before, html[data-theme="dark"].hm-js .navbar.is-off::before { background-color: transparent; }
html[data-theme="dark"]:not(.hm-js) .navbar { background-color: rgba(6, 12, 33, 0.97); }
html[data-theme="dark"] .book-call_bar .cta_bar { background-color: rgba(6, 12, 33, var(--glass-a, 0.85)); border-top-color: rgba(242, 243, 247, 0.1); color: #f2f3f7; }
html[data-theme="dark"] .book-call_bar:hover .cta_bar { background-color: rgba(14, 19, 40, 0.94); }
html[data-theme="dark"] .book-call_bar .book-call-text { color: #f2f3f7; }
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  html[data-theme="dark"].hm-js .navbar::before { background-color: rgba(6, 12, 33, calc(0.97 * var(--nav-o, 0))); }
  html[data-theme="dark"] .book-call_bar .cta_bar { background-color: rgba(6, 12, 33, 0.97); }
}

/* ---- v35.1 theme toggle (moon / sun), PN live spec ----------------------------
   Matches the LIVE Public Network toggle (/workspace/handoff/theme-toggle-spec.md,
   from PN www site/css/overrides.css lines 1176-1194 and site/js/theme-toggle.js):
   Phosphor regular icon at 17px in a 28px round button, no padding, transparent
   background, colour only on hover (light #78787a -> #1d1d1f, dark #86868b ->
   #f2f3f7), 160ms ease colour transition, instant icon swap (moon in light, sun
   in dark), the suggested focus-visible outline, no pressed state. The icons are
   inline SVGs of the same Phosphor regular paths (1em glyph = 17px box), so no
   icon font loads. It sits just left of Client login, always shown like Client
   login, and is hidden with no JS (html.theme-js is set by the head script).
   Light mode over the dark hero and band: the spec grey passes at rest (4.4:1)
   but its hover ink does not, so there the toggle uses PN's dark-mode pair
   (#86868b -> #f2f3f7). While the hero background is mid-fade (.is-shade-mid)
   no grey passes 3:1, so it follows Client login: navy, then white.       */
.theme_toggle { display: none; }
html.theme-js .theme_toggle {
  -webkit-appearance: none; appearance: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; margin: 0 0.5rem 0 0; padding: 0;
  border: none; border-radius: 50%; background: transparent; color: #78787a;
  cursor: pointer; pointer-events: auto; -webkit-tap-highlight-color: transparent;
  transition: color 160ms ease;
}
html.theme-js .theme_toggle:hover { color: #1d1d1f; }
html.theme-js .theme_toggle svg { width: 17px; height: 17px; display: block; fill: currentColor; }
html.theme-js .theme_toggle .theme_icon--sun { display: none; }
html.theme-js[data-theme="dark"] .theme_toggle .theme_icon--sun { display: block; }
html.theme-js[data-theme="dark"] .theme_toggle .theme_icon--moon { display: none; }
html.theme-js .theme_toggle:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
html.theme-js[data-theme="dark"] .theme_toggle { color: #86868b; }
html.theme-js[data-theme="dark"] .theme_toggle:hover { color: #f2f3f7; }
html.hm-js.theme-js:not([data-theme="dark"]) .navbar.is-link-dark .theme_toggle { color: #86868b; }
html.hm-js.theme-js:not([data-theme="dark"]) .navbar.is-link-dark .theme_toggle:hover { color: #f2f3f7; }
html.hm-js.theme-js:not([data-theme="dark"]) .navbar.is-shade-mid .theme_toggle,
html.hm-js.theme-js:not([data-theme="dark"]) .navbar.is-shade-mid .theme_toggle:hover { color: #060c21; }
html.hm-js.theme-js:not([data-theme="dark"]) .navbar.is-shade-mid.is-link-dark .theme_toggle,
html.hm-js.theme-js:not([data-theme="dark"]) .navbar.is-shade-mid.is-link-dark .theme_toggle:hover { color: #fff; }
.navbar .nav-menu { display: flex; align-items: center; }
/* Logos with white knockouts (Uniqlo, Leica, MJZ, Levi's): a plain invert
   keeps the knockout readable (navy turns light, white turns dark). */
html[data-theme="dark"] :is(.logos_image, .section_testimonials img.image):is([src*="_Uniqlo"], [src*="_Leica"], [src*="_MJZ"], [src*="_Levis"]) { filter: invert(1) hue-rotate(180deg) brightness(0.96); }
html[data-theme="dark"] .hero_stack .hero_srr, html.hm-cv[data-theme="dark"] .hero_stack .hero_srr { color: #f2f3f7; }
/* v35.3: small phones only (below 390). Client login stays on one line, so
   it no longer wraps down over the rising hero wordmark. The toggle gap
   drops from 8px to 6px to make room at 320; the toggle stays 28px. 390 and
   up are untouched. */
@media (max-width: 389px) {
  .navbar .nav-link-2 { white-space: nowrap; }
  html.theme-js .theme_toggle { margin-right: 0.375rem; }
}
/* v35.3: the nav logo follows the tagline sentence (--logo-o, the same
   value as --cv-tag-o), not the glass. Over the navy hero and the black
   band (.is-link-dark, light mode) it is white like Client login; while the
   hero or glass is mid-way (.is-shade-mid) it follows Client login too. */
html.hm-js .navbar .logo_wordmark { opacity: var(--logo-o, 0); }
html.hm-js .navbar.is-off .logo_wordmark { opacity: var(--logo-o, 0); visibility: visible; }
html.hm-js .navbar.is-logo-off .logo_wordmark { opacity: 0; visibility: hidden; }
html.hm-js .navbar .logo_wordmark { pointer-events: none; }
html.hm-js .navbar.is-logo-on .logo_wordmark { pointer-events: auto; }
html.hm-js:not([data-theme="dark"]) .navbar.is-link-dark .logo_wordmark { color: #fff; }
/* v35.3 How: the line runs from the first step dot and ends exactly at the
   third (last) dot. It is drawn per step, from each dot's center down to
   the next one (step height plus the 2.5rem row gap), so nothing continues
   below the last dot, with or without JS. The travelling dot is a bright
   red-orange, #ff4a1c (3.27:1 on #fcfcfc, 5.73:1 on #060c21). */
.section_the-how .how_steps::before { content: none; }
.section_the-how .how_steps > .how_step:not(:last-child)::after {
  content: ""; position: absolute; left: calc(-2.25rem + 0.25rem); top: calc(2.25rem + 0.5px);
  width: 1px; height: calc(100% + 2.5rem); background-color: rgba(6, 12, 33, 0.14); pointer-events: none;
}
html[data-theme="dark"] .section_the-how .how_steps > .how_step:not(:last-child)::after { background-color: rgba(242, 243, 247, 0.16); }
html.hm-howdot .section_the-how .how_track-dot,
html[data-theme="dark"].hm-howdot .section_the-how .how_track-dot { background-color: #ff4a1c; }
html.hm-howdot .section_the-how .how_step-dot { z-index: 1; }
/* v35.3 pricing type: plan names, prices and the lead line ("One focus.
   Cover one department or one gap.") stay full white (the cards are navy
   in light mode, #171d31 in dark); the "requests in motion" line and the
   feature list drop to a softer grey, #a3a8b8 (8.0:1 on #060c21, 7.0:1 on
   #171d31). */
.section_pricing .pricing_card .pricing_name,
.section_pricing .pricing_card .pricing_amount,
.section_pricing .pricing_card .pricing_team,
.section_pricing .pricing_card .pricing_team strong,
html[data-theme="dark"] .section_pricing .pricing_card .pricing_name,
html[data-theme="dark"] .section_pricing .pricing_card .pricing_amount,
html[data-theme="dark"] .section_pricing .pricing_card .pricing_team,
html[data-theme="dark"] .section_pricing .pricing_card .pricing_team strong { color: #fff; }
.section_pricing .pricing_card .pricing_line,
.section_pricing .pricing_card .pricing_list li,
html[data-theme="dark"] .section_pricing .pricing_card .pricing_line,
html[data-theme="dark"] .section_pricing .pricing_card .pricing_list li { color: #a3a8b8; }
/* v35.3 Book a Call bar: only a shade brighter than the page behind it.
   Light mode over light sections keeps the near-white glass (a hair above
   #fcfcfc / #f5f5f7); over navy sections (.is-over-dark, set by
   hero-motion.js) it is a faint white lift with white text instead of the
   bright #d9dae0 panel. Dark mode: a faint white lift over every section,
   no navy wash. */
.book-call_bar .cta_bar { transition: background-color 0.25s ease, color 0.25s ease, border-color 0.25s ease; }
.book-call_bar .book-call-text { transition: color 0.25s ease; }
html:not([data-theme="dark"]) .book-call_bar.is-over-dark .cta_bar { background-color: rgba(255, 255, 255, 0.07); border-top-color: rgba(255, 255, 255, 0.1); color: #fff; }
html:not([data-theme="dark"]) .book-call_bar.is-over-dark:hover .cta_bar { background-color: rgba(255, 255, 255, 0.13); }
html:not([data-theme="dark"]) .book-call_bar.is-over-dark .book-call-text { color: #fff; }
html:not([data-theme="dark"]) .book-call_bar.is-over-dark .cta_bar:focus-visible { outline-color: #fff; }
html[data-theme="dark"] .book-call_bar .cta_bar { background-color: rgba(255, 255, 255, 0.05); border-top-color: rgba(242, 243, 247, 0.1); }
html[data-theme="dark"] .book-call_bar:hover .cta_bar { background-color: rgba(255, 255, 255, 0.1); }
/* v35.3 FAQ end: the Subscribe. Request. Receive. line is removed; the
   copyright moves up into its spot, with that line's 0.5rem spacing. */
.section_the-faqs .faq_end-credit { margin-top: 0.5rem !important; }
/* v35.3 statements ("Our approach: remove all distraction." and "Hand it
   over. Get back to work."): more air between the big lines, 1 to 1.12. */
.one-liner_wrapper h2.statement_type { line-height: 1.12; }
/* v35.3 bar lift without the 180% saturation, which tinted it blue over navy. */
html:not([data-theme="dark"]) .book-call_bar.is-over-dark .cta_bar,
html[data-theme="dark"] .book-call_bar .cta_bar { -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px); }
/* v35.3 the Production work grid is gone, so What we do (navy) now meets
   the approach statement. To keep neighbours distinct, the approach band
   turns light grey with navy type in light mode (#f5f5f7, between navy
   What we do and #fcfcfc How) and #0e1328 in dark (between #030713 and
   #060c21 How). */
.section_one-liner2 { background-color: #f5f5f7; background-image: none; }
.section_one-liner2 .one-liner_wrapper h2.statement_type,
.section_one-liner2 .one-liner_wrapper h2.statement_type * { color: #060c21; }
html[data-theme="dark"] .section_one-liner2 { background-color: #0e1328; }
html[data-theme="dark"] .section_one-liner2 .one-liner_wrapper h2.statement_type,
html[data-theme="dark"] .section_one-liner2 .one-liner_wrapper h2.statement_type * { color: #f2f3f7; }
/* ---- v35.5 one nav and bar look per theme (Weston) ------------------------
   The v35.4 per-section switching is reverted: the nav and the Book a Call
   bar never change colour on scroll; each has one style, tied only to the
   theme, and both match in every section.
     Light: white glass rgba(255,255,255,0.55) with navy content (logo,
     Client login, toggle #060c21). Over #060c21 it lands at #8f929b, where
     navy text is 6.2:1; over light sections it is a barely-there tint.
     Dark: navy glass rgba(15,21,41,0.9) with #f2f3f7 content.
   Blur 20px, no saturation boost (none below 1280, see the simple hero).
   The nav's glass still fades in with --nav-o, once, at the end of the
   hero; the hero itself keeps its own handling (no glass, white content
   on the navy hero and band).                                          */
html.hm-js .navbar::before {
  background-color: rgba(255, 255, 255, calc(0.55 * var(--nav-o, 0)));
  -webkit-backdrop-filter: blur(calc(20px * var(--nav-o, 0)));
  backdrop-filter: blur(calc(20px * var(--nav-o, 0)));
}
html[data-theme="dark"].hm-js .navbar::before { background-color: rgba(15, 21, 41, calc(0.9 * var(--nav-o, 0))); }
html.hm-js .navbar.is-off::before,
html[data-theme="dark"].hm-js .navbar.is-off::before { background-color: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; }
html.hm-js.theme-js:not([data-theme="dark"]) .navbar .theme_toggle { color: #060c21; }
html.hm-js.theme-js:not([data-theme="dark"]) .navbar .theme_toggle:hover { color: #3a4058; }

/* The bar: shown by hero-motion.js (.hm-bar-on) once the five words have
   finished, with a gentle 0.7s slide and fade; main.js's own trigger no
   longer shows it on its own. */
html.hm-js .book-call_bar,
html.hm-js .book-call_bar.is-visible {
  transform: translate3d(0, 100%, 0); opacity: 0; visibility: hidden;
  transition: transform 0.7s var(--reveal-ease), opacity 0.7s ease, visibility 0s linear 0.7s;
}
html.hm-js .book-call_bar.hm-bar-on,
html.hm-js .book-call_bar.hm-bar-on.is-visible {
  transform: translate3d(0, 0, 0); opacity: 1; visibility: visible;
  transition: transform 0.7s var(--reveal-ease), opacity 0.7s ease, visibility 0s linear 0s;
}
@media (prefers-reduced-motion: reduce) {
  html.hm-js .book-call_bar, html.hm-js .book-call_bar.hm-bar-on { transition: none !important; }
}
html .book-call_bar .cta_bar,
html[data-theme="dark"] .book-call_bar .cta_bar,
html:not([data-theme="dark"]) .book-call_bar.is-over-dark .cta_bar {
  background-color: rgba(255, 255, 255, 0.55);
  -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px);
  border-top-color: rgba(6, 12, 33, 0.08); color: #060c21;
}
html .book-call_bar .book-call-text,
html:not([data-theme="dark"]) .book-call_bar.is-over-dark .book-call-text { color: #060c21; }
html[data-theme="dark"] .book-call_bar .cta_bar { background-color: rgba(15, 21, 41, 0.9); border-top-color: rgba(255, 255, 255, 0.08); color: #f2f3f7; }
html[data-theme="dark"] .book-call_bar .book-call-text { color: #f2f3f7; }
html .book-call_bar:hover .cta_bar { background-color: rgba(255, 255, 255, 0.75); }
html[data-theme="dark"] .book-call_bar:hover .cta_bar { background-color: rgba(15, 21, 41, 1); }
html[data-theme="dark"] .book-call_bar .cta_bar:focus-visible { outline-color: #fff; }

/* ---- v35.5 simple hero below desktop (Weston) -----------------------------
   html.hm-simple = JS on and narrower than 1280px. No pin and no scroll
   scrubbing: hero-motion.js only toggles two classes, and these CSS
   transitions (opacity and transform only) do the motion.
     .hm-s-out (past 40px of scroll): the big name, subline and logo bar fade
     and scale to 0.96 (0.4s / 0.5s) while the shade takes the hero to navy
     (0.5s, linear); the nav logo fades in only after the name is gone
     (0.3s from 0.4s in), so the two names never show together.
     .hm-s-tag (tagline band top 85% down the screen): the tagline fades and
     rises 24px into place (0.6s).
   Client login and the logo switch white/navy at the shade's best-contrast
   moment (270ms in, 230ms back). (v35.6: the nav and bar are static; see
   the v35.6 block.) Reduced motion: the same states, no
   transitions. The hero keeps min-height 100svh (fixed 600px where svh is
   not supported). Desktop (1280 and up) is untouched.                    */
@supports not (min-height: 100svh) {
  html.hm-simple .section_header { min-height: 37.5rem !important; }
}
html.hm-simple .hero_stack .hero_wordmark,
html.hm-simple .hero_stack .hero_srr {
  opacity: 1; transform: none; visibility: visible; will-change: opacity, transform;
  transition: opacity 0.4s ease, transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1), visibility 0s linear 0s;
}
html.hm-simple.hm-s-out .hero_stack .hero_wordmark,
html.hm-simple.hm-s-out .hero_stack .hero_srr {
  opacity: 0; transform: scale(0.96); visibility: hidden;
  transition: opacity 0.4s ease, transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1), visibility 0s linear 0.5s;
}
html.hm-simple.hm-logos-ready .section_header > .client_logo-bar { opacity: 1; transition: opacity 0.4s ease; }
html.hm-simple.hm-s-out.hm-logos-ready .section_header > .client_logo-bar,
html.hm-simple.hm-s-out .section_header > .client_logo-bar { opacity: 0; }
html.hm-simple .hero_shade { opacity: 0; transition: opacity 0.5s linear; }
html.hm-simple.hm-s-out .hero_shade { opacity: 1; }
html.hm-simple .section_tagline .tagline_text {
  opacity: 0; will-change: opacity; transition: opacity 0.3s ease;
}
html.hm-simple.hm-s-out .section_tagline .tagline_text { opacity: 1; transition: opacity 0.5s ease 0.2s; }
html.hm-simple .navbar .logo_wordmark { transition: opacity 0.2s ease, color 0s linear 230ms; }
html.hm-simple.hm-s-out .navbar .logo_wordmark { transition: opacity 0.3s ease 0.4s, color 0s linear 270ms; }
html.hm-simple .navbar.is-off .nav-link-2 { transition: color 0s linear 230ms; }
html.hm-simple.hm-s-out .navbar.is-off .nav-link-2 { transition: color 0s linear 270ms; }
/* The theme glass comes in (0.2s, linear) once the tagline band reaches
   Client login. Light mode: the content switches white to navy 162ms in
   (navy to white 38ms in on the way back), the best-contrast point of
   that fade over the navy band. Over the navy hero the light-mode toggle
   is white like Client login, so it switches with it. */
html.hm-simple .navbar::before { transition: background-color 0.2s linear; }
html.hm-simple .navbar.is-on .nav-link-2,
html.hm-simple .navbar.is-on .logo_wordmark,
html.hm-simple.theme-js .navbar.is-on .theme_toggle { transition: color 0s linear 162ms; }
html.hm-simple.hm-js .navbar.is-off.is-from-glass .nav-link-2,
html.hm-simple.hm-js .navbar.is-off.is-from-glass .logo_wordmark,
html.hm-simple.hm-js.theme-js .navbar.is-off.is-from-glass .theme_toggle { transition: color 0s linear 38ms; }
html.hm-simple.hm-js.theme-js:not([data-theme="dark"]) .navbar.is-link-dark .theme_toggle,
html.hm-simple.hm-js.theme-js:not([data-theme="dark"]) .navbar.is-link-dark .theme_toggle:hover { color: #fff; }
/* Light mode: the toggle is navy on the light hero and white on the navy
   one, and switches at the same moment as Client login (no easing), so it
   never sits on the mid-way shade in a colour that cannot read there. */
html.hm-simple.theme-js .navbar.is-off .theme_toggle { transition: color 0s linear 230ms; }
html.hm-simple.hm-s-out.theme-js .navbar.is-off .theme_toggle { transition: color 0s linear 270ms; }
html.hm-simple.hm-reduce .hero_stack .hero_wordmark,
html.hm-simple.hm-reduce .hero_stack .hero_srr,
html.hm-simple.hm-reduce .section_header > .client_logo-bar,
html.hm-simple.hm-reduce .hero_shade,
html.hm-simple.hm-reduce .section_tagline .tagline_text,
html.hm-simple.hm-reduce .navbar .logo_wordmark,
html.hm-simple.hm-reduce .navbar .nav-link-2,
html.hm-simple.hm-reduce.theme-js .navbar .theme_toggle,
html.hm-simple.hm-reduce .navbar::before { transition: none !important; }
html.hm-simple.hm-reduce .hero_stack .hero_wordmark,
html.hm-simple.hm-reduce .hero_stack .hero_srr { transform: none; }

/* ---- v35.6 static nav and Book a Call bar (Weston) -------------------------
   Simply translucent: one static glass per theme from the first pixel,
   over the hero too, at every width. No glass arriving, no colour change,
   no transitions or animations on background, backdrop-filter, colour,
   border or shadow for the nav, its toggle and Client login, or the bar.
   hero-motion.js no longer sets any nav glass or colour class.
     Light: rgba(255,255,255,0.55), navy logo, Client login and toggle.
     Dark:  rgba(15,21,41,0.9), #f2f3f7 logo and Client login, toggle #86868b.
   Both: backdrop-filter blur(18px) saturate(1.2), static. The bar has no
   box-shadow and no shading on ::before or ::after. The bar keeps its fade
   and slide in after Iterate (opacity and transform only); the nav logo
   keeps its fade with the tagline (opacity only).                        */
html.hm-js .navbar::before,
html.hm-js .navbar.is-off::before,
html.hm-pre .navbar::before,
html:not(.hm-js) .navbar {
  background-color: rgba(255, 255, 255, 0.55) !important;
  -webkit-backdrop-filter: blur(18px) saturate(1.2) !important;
  backdrop-filter: blur(18px) saturate(1.2) !important;
  box-shadow: none !important; background-image: none !important;
  transition: none !important; animation: none !important;
}
html[data-theme="dark"].hm-js .navbar::before,
html[data-theme="dark"].hm-js .navbar.is-off::before,
html[data-theme="dark"].hm-pre .navbar::before,
html[data-theme="dark"]:not(.hm-js) .navbar { background-color: rgba(15, 21, 41, 0.9) !important; }
html.hm-js .navbar { background-color: transparent !important; -webkit-backdrop-filter: none !important; backdrop-filter: none !important; box-shadow: none !important; }
html .navbar .nav-link-2,
html .navbar .theme_toggle,
html .navbar .theme_toggle svg { transition: none !important; animation: none !important; }
html.hm-js .navbar .logo_wordmark { transition: none !important; animation: none !important; }
html:not([data-theme="dark"]) .navbar .logo_wordmark,
html:not([data-theme="dark"]) .navbar .nav-link-2,
html.theme-js:not([data-theme="dark"]) .navbar .theme_toggle { color: #060c21 !important; }
html.theme-js:not([data-theme="dark"]) .navbar .theme_toggle:hover { color: #3a4058 !important; }
html[data-theme="dark"] .navbar .logo_wordmark,
html[data-theme="dark"] .navbar .nav-link-2 { color: #f2f3f7 !important; }
html.theme-js[data-theme="dark"] .navbar .theme_toggle { color: #86868b !important; }
html.theme-js[data-theme="dark"] .navbar .theme_toggle:hover { color: #f2f3f7 !important; }
html .book-call_bar,
html .book-call_bar::before, html .book-call_bar::after,
html .book-call_bar .cta_bar, html .book-call_bar .cta_bar::before, html .book-call_bar .cta_bar::after {
  box-shadow: none !important; background-image: none !important;
}
html .book-call_bar::before, html .book-call_bar::after,
html .book-call_bar .cta_bar::before, html .book-call_bar .cta_bar::after { content: none !important; }
html .book-call_bar .cta_bar,
html .book-call_bar:hover .cta_bar {
  background-color: rgba(255, 255, 255, 0.55) !important; /* v35.25: same glass as the nav (Weston) */
  -webkit-backdrop-filter: blur(18px) saturate(1.2) !important;
  backdrop-filter: blur(18px) saturate(1.2) !important;
  border-top-color: transparent !important; color: #060c21 !important;
  transition: none !important; animation: none !important;
}
html[data-theme="dark"] .book-call_bar .cta_bar,
html[data-theme="dark"] .book-call_bar:hover .cta_bar { background-color: rgba(15, 21, 41, 0.9) !important; color: #f2f3f7 !important; }
html .book-call_bar .book-call-text { color: #060c21 !important; transition: none !important; animation: none !important; }
html[data-theme="dark"] .book-call_bar .book-call-text { color: #f2f3f7 !important; }

/* ---- v35.6 tagline in place, held; nav hidden until What we do (Weston) ----
   The tagline replaces the hero text exactly in place: the tagline layer
   covers the header and hero-motion.js measures, once per layout, the
   offset that puts the tagline's center on the hero text's center
   (--tag-dy, a static transform, no rise). Desktop keeps the v35.5 pin and
   lock. Below 1280 the same overlay is held by plain CSS position: sticky
   (the header and the tagline stick at top 0 for an extra 60svh of scroll,
   400px where svh is not supported), with no JS scrubbing; the tagline
   crossfades in with .hm-s-out.
   The whole nav is hidden (opacity 0, not clickable) through the hero and
   the hold. .hm-nav-in (the top of What we do has reached the nav's bottom
   edge) fades it in once, opacity only, 0.22s; it fades out above that.
   Keyboard focus inside the nav shows it. Its glass, blur and colours never
   transition. No JS: the static nav, always visible.                    */
html.hm-cv .section_tagline .tagline_text { transform: translate3d(0, var(--tag-dy, 0px), 0); }
html.hm-simple .hero_curtain > .section_header { position: sticky; top: 0; z-index: 0; }
html.hm-simple .hero_curtain > .section_tagline {
  position: sticky; top: 0; z-index: 1;
  height: var(--hero-h, 100svh); margin-top: calc(-1 * var(--hero-h, 100svh));
  display: flex; align-items: center; justify-content: center;
  background-color: transparent; pointer-events: none;
}
html.hm-simple[data-theme="dark"] .hero_curtain > .section_tagline { background-color: transparent; }
html.hm-simple .hero_curtain > .section_tagline > .padding-global { width: 100%; height: auto; min-height: 0; align-self: center; }
html.hm-simple .section_tagline .tagline_text { padding-top: 0; padding-bottom: 0; }
html.hm-simple .hero_pin { display: block; height: 400px; height: 60svh; }
html.hm-js .navbar { opacity: 0; transition: opacity 0.22s ease; }
html.hm-js .navbar.hm-nav-in,
html.hm-js .navbar.hm-nav-top,
html.hm-js .navbar:focus-within { opacity: 1; }
html.hm-js .navbar:not(.hm-nav-in):not(.hm-nav-top):not(:focus-within),
html.hm-js .navbar:not(.hm-nav-in):not(.hm-nav-top):not(:focus-within) * { pointer-events: none !important; }
html.hm-js .navbar.hm-nav-in .logo_wordmark,
html.hm-js .navbar.hm-nav-in .nav-link-2,
html.hm-js .navbar.hm-nav-in .theme_toggle,
html.hm-js .navbar.hm-nav-top .nav-link-2,
html.hm-js .navbar.hm-nav-top .theme_toggle { pointer-events: auto; }
html.hm-js .navbar .logo_wordmark,
html.hm-js .navbar.is-off .logo_wordmark,
html.hm-js .navbar.is-logo-off .logo_wordmark,
html.hm-pre .navbar .logo_wordmark { opacity: 1 !important; visibility: visible !important; }
@media (prefers-reduced-motion: reduce) { html.hm-js .navbar { transition: none; } }
html.hm-pre .navbar { opacity: 0; pointer-events: none; }

/* ---- v35.7 top-right links, nav after the pillars, bar after Pricing -------
   Nav states (hero-motion.js updateNavIn):
     .hm-nav-top  over the hero text: only Client login and the toggle, no
                  logo and no glass (transparent), navy (light) or #f2f3f7
                  (dark) as in v35.6.
     no class     from the moment the on-demand line comes in: the whole nav
                  is hidden (opacity 0, not clickable).
     .hm-nav-in   the top of the pillar row reaches the nav's bottom edge:
                  logo, toggle and Client login on the static v35.6 glass.
   Only the nav's own opacity fades (0.22s). The glass layer and the logo
   are simply on or off: they switch on at once (the nav is at opacity 0 at
   that moment) and switch off only after the nav has faded out (a 0.22s
   delay, no fade), so neither ever visibly snaps; nothing about the glass
   (colour, blur) is ever transitioned. Keyboard focus shows the full nav.
   Book a Call bar: shown once Pricing has fully scrolled into view
   (.hm-bar-on), opacity only, 0.3s; the bar is a translucent tone of the
   page (light rgba(245,245,247,0.9) with navy, dark rgba(15,21,41,0.9) with
   #f2f3f7), same static blur, no shadow. Reduced motion: instant.        */
html.hm-js .navbar::before,
html.hm-js .navbar .logo_wordmark { opacity: 1 !important; visibility: visible !important; transition: none !important; }
html.hm-js .navbar:not(.hm-nav-in):not(:focus-within)::before,
html.hm-js .navbar:not(.hm-nav-in):not(:focus-within) .logo_wordmark {
  opacity: 0 !important; visibility: hidden !important;
  transition: opacity 0s linear 0.22s, visibility 0s linear 0.22s !important;
}
html.hm-js .navbar.hm-nav-top:not(.hm-nav-in):not(:focus-within) .logo_wordmark { pointer-events: none !important; }
html.hm-js .book-call_bar,
html.hm-js .book-call_bar.is-visible {
  transform: none !important; opacity: 0; visibility: hidden;
  transition: opacity 0.3s ease, visibility 0s linear 0.3s !important;
}
html.hm-js .book-call_bar.hm-bar-on,
html.hm-js .book-call_bar.hm-bar-on.is-visible {
  transform: none !important; opacity: 1; visibility: visible;
  transition: opacity 0.3s ease, visibility 0s linear 0s !important;
}
@media (prefers-reduced-motion: reduce) {
  html.hm-js .navbar,
  html.hm-js .navbar:not(.hm-nav-in):not(:focus-within)::before,
  html.hm-js .navbar:not(.hm-nav-in):not(:focus-within) .logo_wordmark,
  html.hm-js .book-call_bar, html.hm-js .book-call_bar.hm-bar-on { transition: none !important; }
}

/* ---- v35.8 hero is the wordmark only; Client login back in the nav (Weston)
   The v35.7 hero actions (Client login button, Book a call link) are gone.
   An empty spacer (::after, no content, not read out) keeps their height,
   so the wordmark and the tagline stay exactly where they were.
   Over the hero (.hm-nav-top) the nav shows the theme toggle and the small
   Client login link at the top right as in v35.6: no logo, no glass. Both
   fade out with the nav as the on-demand line comes in; the full nav fades
   in at the Plan, Design, Develop row (.hm-nav-in).                        */
.header_wrapper-update.hero_stack::after {
  content: ""; display: block; flex: none; width: 1px;
  height: calc(clamp(1.75rem, 3vw, 3rem) + 48px);
}
@media screen and (max-width: 479px) {
  .header_wrapper-update.hero_stack::after { height: calc(1.5rem + 48px); }
}
html.hm-js .navbar.hm-nav-top:not(.hm-nav-in) .logo_wordmark { visibility: hidden !important; pointer-events: none !important; }
html.hm-js .navbar.hm-nav-top:not(.hm-nav-in)::before { opacity: 0 !important; visibility: hidden !important; }
/* v35.7.1: bigger tap area for the theme toggle. The button and its 17px icon
   keep the same 28px box, size and position at every width; a transparent
   ::after reaches 8px past each edge, so the hit area is 44x44. */
html.theme-js .theme_toggle { position: relative; }
html.theme-js .theme_toggle::after {
  content: ""; position: absolute; top: 50%; left: 50%;
  width: 44px; height: 44px; transform: translate(-50%, -50%);
  background: transparent;
}
/* v35.8: below 390 the gap from the toggle to Client login is 6px, so the
   44x44 hit area moves 2px to the left there (10px left, 6px right) and
   ends exactly at Client login's left edge. The 28px box and the 17px icon
   do not move. */
@media (max-width: 389px) {
  html.theme-js .theme_toggle::after { left: calc(50% - 2px); }
}

/* ---- v35.8 phones: the on-demand tagline centered in the visible viewport
   During the hold the tagline layer sticks at top 0 with the hero's height
   (--hero-h); this moves the line so its center sits at half the visible
   viewport height (dvh follows Safari's toolbars; svh, then vh, as
   fallbacks), not on the hero text. Text centered. 768 and up unchanged. */
@media screen and (max-width: 767px) {
  html.hm-simple.hm-cv .section_tagline .tagline_text {
    text-align: center;
    transform: translate3d(0, calc(50vh - var(--hero-h, 100vh) / 2), 0);
    transform: translate3d(0, calc(50svh - var(--hero-h, 100svh) / 2), 0);
    transform: translate3d(0, calc(50dvh - var(--hero-h, 100dvh) / 2), 0);
  }
}

/* ---- v35.9 sticky nav from the pillar section (Weston) -----------------------
   hero-motion.js puts a dock (.nav_dock, the nav's height, --nav-h) in the
   page at the start of the five-word pillar list (v35.10; v35.9 had it
   before What we do) and moves the nav into it. Over the hero
   and through the tagline hold the nav stays fixed (top state, then
   hidden). Once the dock is on screen (.hm-nav-dock) the full nav sits in
   the dock, travels up with the page and, because the dock is sticky at
   top 0, sticks there for the rest of the page. No fade on the way in or
   out of the dock (.hm-nav-snap). Anchor jumps land below the stuck nav
   (scroll-padding-top). No JS: no dock, the static nav as before.        */
html.hm-dock { scroll-padding-top: var(--nav-h, 120px); }
.nav_dock { position: -webkit-sticky; position: sticky; top: 0; z-index: 4500; height: var(--nav-h, 120px); pointer-events: none; }
html.hm-js .nav_dock > .navbar.hm-nav-dock { position: absolute; top: 0; left: 0; right: 0; opacity: 1; transition: none !important; }
html.hm-js .navbar.hm-nav-snap { transition: none !important; }

/* ---- v35.9 more room in the pillar section (Weston: not cramped) -------------
   Before: section padding 160px (128px on phones), intro gap 64px, pillar
   rows 64px apart (40px on phones), columns 80px apart, 12px from a
   pillar's name to its line, tile padding 32px (28px by 24px on phones).  */
#offer .padding-section-large { padding-top: 13rem; padding-bottom: 13rem; }
#offer .offer_intro { margin-bottom: 6rem; }
.section_services .services_grid--pillars { row-gap: 6.5rem; column-gap: 6rem; }
.section_services .services_grid--pillars .services_desc { margin-top: 1.25rem; line-height: 1.6; }
.section_services .services_grid--pillars > .offer_start { padding: 2.75rem; }
@media screen and (min-width: 768px) {
  .section_services .services_grid--pillars > .offer_start { margin-top: calc(-2.75rem - 1px); }
}
@media screen and (max-width: 767px) {
  #offer .padding-section-large { padding-top: 10rem; padding-bottom: 10rem; }
  #offer .offer_intro { margin-bottom: 5rem; }
  .section_services .services_grid--pillars { row-gap: 4.5rem; }
  .section_services .services_grid--pillars .services_desc { margin-top: 1rem; }
  .section_services .services_grid--pillars > .offer_start { padding: 2.25rem 1.75rem; }
}

/* ---- v35.10 translucent buttons (Weston) --------------------------------------
   Every button-styled control (the Book a call button in the Book a call
   tile and the three pricing Book a call buttons) is glass like the nav: a
   translucent light fill with a hairline and a backdrop blur, white text.
   They all sit on navy (the Offer, the pricing cards), so white text keeps
   well over 4.5:1. Hover: a little more fill. The Book a Call bar is the
   nav's glass already (unchanged).                                       */
.offer_start .offer_start-button,
.pricing_card .pricing_cta,
html[data-theme="dark"] .section_pricing a.button.pricing_cta,
html[data-theme="dark"] .section_services a.offer_start-button {
  background-color: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.32);
  color: #fff;
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
}
.offer_start .offer_start-button:hover,
.pricing_card .pricing_cta:hover,
html[data-theme="dark"] .section_pricing a.button.pricing_cta:hover,
html[data-theme="dark"] .section_services a.offer_start-button:hover {
  background-color: rgba(255, 255, 255, 0.24);
  border-color: rgba(255, 255, 255, 0.5);
  color: #fff;
}

/* ---- v35.11 five words: even top and bottom space under the stuck nav (Weston)
   The stuck nav's glass reads as part of this white section, so the space
   that shows above Plan. starts at the nav's logo row (its bottom is 46px
   above the nav's bottom edge), not at the nav's edge. The top padding
   drops by those 46px, so logo row to Plan. equals Iterate. to the
   section's bottom (112px desktop, 64px phones; bottom padding unchanged).
   No JS (no dock): unchanged.                                             */
html.hm-dock .section_words .words_sticky { padding-top: calc(7rem - 46px); }
@media screen and (max-width: 767px) {
  html.hm-dock .section_words .words_sticky { padding-top: calc(4rem - 46px); }
}

/* ---- v35.12 What we do grid: three across only where the tile stays wide ----
   Measured: with three columns the Book a call tile keeps its heading on
   one line from a 1320px window up; below that it wraps and the tile
   turns narrow and tall. So three across from 1360px (a little margin),
   two across from 768 to 1359px, one column on phones (unchanged). In two
   across every item is a normal cell: Iterate. and the Book a call tile
   sit side by side in the last row, the tile the same width as the other
   cells (v35.11's full-row spans are gone; Weston). The heading never
   wraps: from 768 to 991px the column gap and the tile's side padding are
   a little smaller so "Book a call" fits its cell on one line.          */
@media screen and (min-width: 768px) and (max-width: 1359px) {
  .section_services .services_grid--pillars { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .section_services .services_grid--pillars > .services_grid-item,
  .section_services .services_grid--pillars > .services_grid-item:nth-child(n+4) { grid-column: auto; }
  .section_services .services_grid--pillars .offer_start-heading { white-space: nowrap; }
}
@media screen and (min-width: 768px) and (max-width: 991px) {
  .section_services .services_grid--pillars { column-gap: 4rem; }
  .section_services .services_grid--pillars > .services_grid-item.offer_start { padding-left: 1.75rem; padding-right: 1.75rem; }
}

/* ---- v35.11 "Our approach: remove all distraction." on the page background ----
   No separate band colour: the band is The How's colour (#fcfcfc, dark
   #060c21), so the two read as one surface (the v35.10 fade overlay is
   gone). The line keeps its fade on scroll.                             */
.section_one-liner2 { background-color: #fcfcfc; background-image: none; }
html[data-theme="dark"] .section_one-liner2 { background-color: #060c21; }
/* The How comes up: the space from the line down to "The How" matches the
   space from the band's top edge down to the line (measured: the line box
   sits 10px into the band's 20rem top padding, and "The How" starts 10px
   below its padding edge; v35.12: re-measured with The How static, the
   v35.11 value had caught its reveal offset). The band keeps its top
   padding.                                                               */
/* v35.32 (Weston): the band's bottom padding equals its top (20rem), so the
   line sits centered with equal space above and below, and The How rests
   at the band's bottom edge, never inside that padding. */
.section_one-liner2 .padding-section-huge { padding-bottom: calc(20rem - 20px); } /* the line box sits 10px inside the content box at both ends, so 300px here gives 310px of space below the line, the same as above */
.section_one-liner2 + .section_the-how .padding-section-large { padding-top: 0; } /* v35.32: The How starts at the band's bottom edge (was calc(20rem - 170px) with no band bottom padding) */

/* ---- v35.21 The How rises with the scroll (Weston) ------------------------------
   hero-motion.js ties The How's heading, intro line and steps block to the
   scroll (inline transform and opacity, reversible) while the approach
   sentence fades out; main.js no longer gives them the one-shot .reveal.
   Ends at translate 0 and opacity 1, so the 310/310 rest gaps hold.     */
html.hm-howrise .section_the-how :is(.heading-style-h1, .more_line-space, .how_steps) { will-change: transform; }
/* v35.32, v35.36: the moment the line has faded out, The How slides UP
   160px (a 0.5s transition, hero-motion.js) into the space it leaves, ending 160px under where the line was
   (the v35.29 gap). The How's own bottom padding gives up the same 160px
   while the rise is wired, so the gap to Pricing stays as before once the
   rise has finished (the bottom is far below the viewport until then).
   Reduced motion and no JS: no rise, full bottom padding.              */
html.hm-howrise .section_one-liner2 + .section_the-how .padding-section-large { padding-bottom: 0; }

/* ---- v35.16 The How steps: no numbers, navy dot beside each title --------------
   index.html drops the 01 / 02 / 03 labels, so each step starts with its
   title. The step dot stays on the line, just before the title, centered on
   the title's first line (1.5rem step padding-top, then half of the
   title's 2rem x 1.1 line, so 2.6rem down).
   The line segments start and end at the dot centers. The travelling dot is
   navy #060c21 in light (was red-orange #ff4a1c); dark uses #f2f3f7
   (v35.17, Lead), as navy would vanish on the dark #060c21 section.                                                       */
.section_the-how .how_steps { --how-dot-c: 2.6rem; }
.section_the-how .how_step-dot { top: calc(var(--how-dot-c) - 4.5px); }
.section_the-how .how_steps > .how_step:not(:last-child)::after { top: var(--how-dot-c); }
html.hm-howdot .section_the-how .how_track-dot { background-color: #060c21; }
html[data-theme="dark"].hm-howdot .section_the-how .how_track-dot { background-color: #f2f3f7; }

/* ---- v35.16 What we do footnote (moved from under the Pricing cards) -----------
   Small, muted, left edge on the grid's left edge, under the grid. The
   section is navy in both themes; #9ba0b0 on #060c21 is 7.4:1.          */
.section_services .offer_footnote { margin: 4rem 0 0; color: #9ba0b0; font-size: 0.875rem; font-weight: 500; line-height: 1.5; text-align: left; }
@media screen and (max-width: 767px) { .section_services .offer_footnote { margin-top: 3rem; } }


/* ---- v35.19 (Weston) -------------------------------------------------------------
   Buttons: the v35.16 solid fills on navy are removed, so the Let's talk
   button and the three pricing Book a call buttons are the v35.10 glass
   again (rgba(255,255,255,0.14), hairline 0.32, saturate(180%) blur(20px)),
   the same as v35.15.

   Let's talk: no container. No glass, border, radius, padding or pull-up;
   it sits in its grid cell like the pillars, heading on the same line as
   the other headings, body spaced like a pillar's text.                   */
html .section_services .services_grid--pillars > .services_grid-item.offer_start {
  background-color: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border: 0;
  border-radius: 0;
  padding: 0;
  margin-top: 0;
}
html .section_services .services_grid--pillars > .offer_start .offer_start-body { margin-top: 1.25rem; }
@media screen and (max-width: 767px) {
  html .section_services .services_grid--pillars > .offer_start .offer_start-body { margin-top: 1rem; }
}

/* Book a Call bar (v35.19): slide only. Shown and hidden by hero-motion.js
   (.hm-bar-on, unchanged trigger). Off below the bottom edge by its own
   height plus 24px (its shadow), opacity 1 throughout, 0.7s smooth
   ease-in-out both ways (v35.20; was 0.45s ease). Replaces the v35.x opacity-only fade (its transform: none and
   transition are !important, so these are too). Reduced motion: instant. */
html.hm-js .book-call_bar,
html.hm-js .book-call_bar.is-visible {
  transform: translate3d(0, calc(100% + 24px), 0) !important; opacity: 1 !important; visibility: hidden;
  transition: transform 0.7s cubic-bezier(0.45, 0, 0.25, 1), visibility 0s linear 0.7s !important;
}
html.hm-js .book-call_bar.hm-bar-on,
html.hm-js .book-call_bar.hm-bar-on.is-visible {
  transform: translate3d(0, 0, 0) !important; opacity: 1 !important; visibility: visible;
  transition: transform 0.7s cubic-bezier(0.45, 0, 0.25, 1), visibility 0s linear 0s !important;
}
@media (prefers-reduced-motion: reduce) {
  html.hm-js .book-call_bar, html.hm-js .book-call_bar.is-visible,
  html.hm-js .book-call_bar.hm-bar-on, html.hm-js .book-call_bar.hm-bar-on.is-visible { transition: none !important; }
}

/* ---- v35.22 The How check-offs (Weston) ---------------------------------------
   Once the travelling dot passes a step, that step's circle turns green with a
   white check (hero-motion.js toggles .is-done; scrolling back up unchecks).   */
html.hm-howdot .section_the-how .how_step-dot {
  transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), background-color 0.25s ease, border-color 0.25s ease;
}
html.hm-howdot .section_the-how .how_step-dot.is-done,
html[data-theme="dark"].hm-howdot .section_the-how .how_step-dot.is-done {
  z-index: 2; background-color: #22c55e; border-color: #22c55e; transform: scale(2);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: center; background-size: 70% 70%;
}

/* ---- v35.26 $99 AEO audit: one quiet block after the Pricing cards ------------
   Sits on the Pricing section's own surface (no card), smaller than the
   cards, left on the grid edge. Label in the eyebrow style, muted body
   (#424242 / #5f6068 tokens), and the existing .button as a navy hairline
   pill rather than a filled one, so it reads quieter than the cards and
   stays apart from every Book a call. Dark: the same tones as the FAQ
   end (#f2f3f7 / #a3a8b8).                                               */
.section_pricing .pricing_audit { margin: 4rem 0 0; max-width: 40rem; }
.section_pricing .pricing_audit-label { margin: 0; color: #5f6068; font-size: 0.875rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.section_pricing .pricing_audit-heading { margin: 0.5rem 0 0; color: #060c21; font-size: 1.75rem; font-weight: 900; line-height: 1.15; }
.section_pricing .pricing_audit-body { margin: 0.75rem 0 0; color: #424242; font-size: 1.125rem; font-weight: 500; line-height: 1.5; }
html .section_pricing a.button.pricing_audit-cta {
  display: inline-block; margin: 1.5rem 0 0; padding: 0.75rem 1.75rem;
  background-color: transparent; color: #060c21; border: 1px solid #060c21; border-radius: 100px;
  font-size: 1rem; font-weight: 700; line-height: 1.2; text-decoration: none;
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
html .section_pricing a.button.pricing_audit-cta:hover { background-color: #060c21; color: #f5f5f7; }
html .section_pricing a.button.pricing_audit-cta:focus-visible { outline: 2px solid #060c21; outline-offset: 3px; }
html[data-theme="dark"] .section_pricing .pricing_audit .pricing_audit-heading { color: #f2f3f7; }
html[data-theme="dark"] .section_pricing .pricing_audit .pricing_audit-label,
html[data-theme="dark"] .section_pricing .pricing_audit .pricing_audit-body { color: #a3a8b8; }
html[data-theme="dark"] .section_pricing a.button.pricing_audit-cta { color: #f2f3f7; border-color: #f2f3f7; }
html[data-theme="dark"] .section_pricing a.button.pricing_audit-cta:hover { background-color: #f2f3f7; color: #060c21; }
html[data-theme="dark"] .section_pricing a.button.pricing_audit-cta:focus-visible { outline-color: #f2f3f7; }
@media screen and (max-width: 767px) {
  .section_pricing .pricing_audit { margin-top: 3rem; }
  .section_pricing .pricing_audit-heading { font-size: 1.5rem; }
  .section_pricing .pricing_audit-body { font-size: 1rem; }
}

/* ---- v35.37 sizzle reel in the tagline layer (Weston) --------------------------
   The reel sits in the tagline layer, under the on-demand line in the markup.
   With motion (html.sz-js.sz-live: the desktop pin or the simple hero, not
   reduced motion) it is laid exactly over the line, centered on the line's
   center (--sz-cy, measured by hero-motion.js), never scaled.
   Desktop pin: hero-motion.js scrubs its opacity (--cv-sz-o) the same way
   the line fades in, once the line has faded out in place; the pin lets go
   only after it is full. Simple hero (below 1280): html.sz-on (a scroll
   trigger at the end of the line's hold) fades the line out (0.4s), then
   the reel in (0.5s, 0.4s later, like the line's own 0.5s fade-in), and
   the hold is longer (120svh) so it is full before the hero scrolls away.
   v35.38: the simple hero is scroll-tied as well (no sz-on), and
   hero-motion.js steps the hero scroll between two stops (line, reel).
   Buttons: the nav glass (light rgba(255,255,255,0.55), dark
   rgba(15,21,41,0.9), blur(18px) saturate(1.2)); 36px on phones.
   Reduced motion and no JS: in flow under the line, full size, poster plus
   the play button (no JS: native controls).                              */
.section_tagline .sizzle_frame {
  position: relative; width: 100%; max-width: 70rem; margin: 2.5rem auto 0;
  aspect-ratio: 16 / 9; border-radius: 1rem; overflow: hidden; background-color: #000;
}
.section_tagline .sizzle_video { display: block; width: 100%; height: 100%; object-fit: cover; background-color: #000; }
html.sz-js.sz-live .section_tagline .container-large { position: relative; }
html.sz-js.sz-live .section_tagline .sizzle_frame {
  position: absolute; left: 50%; top: var(--sz-cy, 50%); margin: 0;
  width: min(100%, 70rem, calc((100vh - 12rem) * 16 / 9));
  transform: translate(-50%, -50%);
  opacity: var(--cv-sz-o, 0); visibility: hidden; pointer-events: none;
}
html.sz-js.sz-live.sz-vis .section_tagline .sizzle_frame { visibility: visible; }
html.sz-js.sz-live.sz-full .section_tagline .sizzle_frame { pointer-events: auto; }
/* simple hero (v35.38): scroll-tied too, so the state is a function of the
   scroll position (hero-motion.js writes --sz-line-o on the line and
   --cv-sz-o on the frame; was class-driven and time-based in v35.37) */
html.sz-js.sz-live.hm-simple.sz-lo .section_tagline .tagline_text { opacity: var(--sz-line-o, 1) !important; transition: none !important; }
html.sz-js.sz-live.hm-simple .hero_pin { height: 800px; height: 120svh; }
.section_tagline .sizzle_controls {
  position: absolute; right: 1rem; bottom: 1rem; display: flex; gap: 0.5rem; z-index: 2;
}
.section_tagline .sizzle_btn:not([hidden]) {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.75rem; height: 2.75rem; padding: 0; margin: 0; border: 0; border-radius: 100px; cursor: pointer;
  color: #060c21; background-color: rgba(255, 255, 255, 0.55);
  -webkit-backdrop-filter: blur(18px) saturate(1.2); backdrop-filter: blur(18px) saturate(1.2);
}
html[data-theme="dark"] .section_tagline .sizzle_btn:not([hidden]) { color: #f2f3f7; background-color: rgba(15, 21, 41, 0.9); }
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .section_tagline .sizzle_btn:not([hidden]) { background-color: rgba(252, 252, 252, 0.97); }
  html[data-theme="dark"] .section_tagline .sizzle_btn:not([hidden]) { background-color: rgba(6, 12, 33, 0.97); }
}
.section_tagline .sizzle_btn:focus { outline: none; }
.section_tagline .sizzle_btn:focus-visible { outline: none; box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #060c21; }
html[data-theme="dark"] .section_tagline .sizzle_btn:focus-visible { box-shadow: 0 0 0 2px #030713, 0 0 0 4px #f2f3f7; }
.section_tagline .sizzle_icon { width: 1.25rem; height: 1.25rem; display: block; }
.section_tagline .sizzle_sound .sizzle_icon--on,
.section_tagline .sizzle_sound[aria-pressed="true"] .sizzle_icon--off,
.section_tagline .sizzle_play .sizzle_icon--pause,
.section_tagline .sizzle_play[aria-pressed="true"] .sizzle_icon--play { display: none; }
.section_tagline .sizzle_sound[aria-pressed="true"] .sizzle_icon--on,
.section_tagline .sizzle_play[aria-pressed="true"] .sizzle_icon--pause { display: block; }
@media screen and (max-width: 767px) {
  .section_tagline .sizzle_frame { border-radius: 0.75rem; margin-top: 2rem; }
  .section_tagline .sizzle_controls { right: 0.5rem; bottom: 0.5rem; gap: 0.375rem; }
  .section_tagline .sizzle_btn:not([hidden]) { width: 2.25rem; height: 2.25rem; }
  .section_tagline .sizzle_icon { width: 1rem; height: 1rem; }
}
/* reduced motion on phones (simple hero): the reel shows with the line,
   not over the light hero before it */
html.sz-js.sz-reduce.hm-simple:not(.hm-s-out) .section_tagline .sizzle_frame { visibility: hidden; }
/* the simple hero's tagline layer ignores the pointer (it lies over the
   header), so the in-flow reel takes it back for its buttons */
html.sz-js.sz-reduce .section_tagline .sizzle_frame { pointer-events: auto; }

/* ---- v35.34 audit entry points (Weston) ---------------------------------------
   Under the Let's talk tile's Book a call (not under any price card or the
   bar): "Not ready for a call? Start with The Audit." to /audit, and a
   footer link "The Audit". The Book a call buttons are unchanged.        */
.offer_start .offer_start-audit { margin: 1rem 0 0; font-size: 1rem; font-weight: 500; line-height: 1.45; color: rgba(255, 255, 255, 0.78); }
.offer_start .offer_start-audit a { color: #fff; font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
.offer_start .offer_start-audit a:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.section_the-faqs .faq_end-links { margin-top: 1rem !important; font-size: 1rem; font-weight: 600; line-height: 1.4; }
.section_the-faqs .faq_end-links a { color: #060c21; text-decoration: underline; text-underline-offset: 3px; }
html[data-theme="dark"] .section_the-faqs .faq_end-links a { color: #f2f3f7; }
.section_the-faqs .faq_link { color: inherit; font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }

/* ---- v35.40 scroll cues (Weston): a thin bouncing down arrow under the
   name, and at the bottom center of the on-demand line and video screens.
   hero-motion.js writes each one's opacity (--cue-o) from the scroll
   position, the same way as its screen, and lets clicks through only
   while it is mostly visible (.cue-on). */
.scroll_cue {
  display: flex; align-items: center; justify-content: center;
  width: 2.75rem; height: 2.75rem; padding: 0; margin: 0;
  border: 0; background: transparent; color: inherit; cursor: pointer;
  opacity: calc(0.55 * var(--cue-o, 1));
  -webkit-tap-highlight-color: transparent;
}
.scroll_cue svg { display: block; width: 22px; height: 22px; animation: cue-bob 1.8s ease-in-out infinite; }
.scroll_cue:hover, .scroll_cue:focus-visible { opacity: calc(0.85 * var(--cue-o, 1)); }
.scroll_cue:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; border-radius: 999px; }
@keyframes cue-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(7px); } }
.scroll_cue--top { margin: 1.25rem auto 0; }
/* v35.48 (Weston): top arrow sits 20px lower, no layout shift. */
.scroll_cue--top { position: relative; top: 20px; }
.scroll_cue--fixed {
  position: fixed; left: 50%; bottom: calc(1.25rem + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%); z-index: 40; color: #fff;
  visibility: hidden; pointer-events: none;
}
html.cue-js .scroll_cue--fixed { visibility: visible; }
html.cue-js .scroll_cue--fixed:not(.cue-on), html.cue-js .scroll_cue--top:not(.cue-on) { pointer-events: none; }
html:not(.cue-js) .scroll_cue--fixed { display: none; }
.scroll_cue--fixed.cue-on { pointer-events: auto; }
@media (max-width: 767px) { .scroll_cue--top { margin-top: 0.75rem; } }
@media (prefers-reduced-motion: reduce) { .scroll_cue svg { animation: none; } }

/* ---- v35.41 sound hint on the reel: while it plays muted only because
   unmuted autoplay was refused, a soft ring pulses on the sound button and
   a glass "Tap for sound" pill shows to its left for about 4s (hero-motion.js
   sets .sz-hint and .sz-hint-label on .section_tagline). Both stop for good
   once sound is turned on or the user mutes on purpose. The pill is a
   pointer shortcut only (hidden from screen readers, not focusable); the
   sound button itself is the accessible control ("Turn sound on"). */
.section_tagline .sizzle_hint {
  position: absolute; right: calc(100% + 0.5rem); top: 50%;
  transform: translateY(-50%) translateX(0.5rem) scale(0.92); transform-origin: right center;
  height: 2.25rem; padding: 0 0.9rem; margin: 0; border: 0; border-radius: 100px;
  white-space: nowrap; font: 500 0.8125rem/1 Figtree, system-ui, sans-serif; letter-spacing: 0.01em;
  color: #060c21; background-color: rgba(255, 255, 255, 0.55);
  -webkit-backdrop-filter: blur(18px) saturate(1.2); backdrop-filter: blur(18px) saturate(1.2);
  opacity: 0; visibility: hidden; pointer-events: none; cursor: pointer;
  transition: opacity 0.35s ease, transform 0.35s ease, visibility 0s linear 0.35s;
}
html[data-theme="dark"] .section_tagline .sizzle_hint { color: #f2f3f7; background-color: rgba(15, 21, 41, 0.9); }
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .section_tagline .sizzle_hint { background-color: rgba(252, 252, 252, 0.97); }
  html[data-theme="dark"] .section_tagline .sizzle_hint { background-color: rgba(6, 12, 33, 0.97); }
}
.section_tagline.sz-hint-label .sizzle_hint {
  opacity: 1; visibility: visible; pointer-events: auto;
  transform: translateY(-50%) translateX(0) scale(1);
  transition: opacity 0.35s ease, transform 0.35s ease, visibility 0s;
}
.section_tagline .sizzle_sound { position: relative; }
.section_tagline.sz-hint .sizzle_sound::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  box-shadow: 0 0 0 1.5px rgba(6, 12, 33, 0.45);
  animation: sz-ring 1.6s ease-out infinite;
}
html[data-theme="dark"] .section_tagline.sz-hint .sizzle_sound::after { box-shadow: 0 0 0 1.5px rgba(242, 243, 247, 0.55); }
@keyframes sz-ring { 0% { transform: scale(1); opacity: 0.9; } 80%, 100% { transform: scale(1.6); opacity: 0; } }
@media screen and (max-width: 767px) {
  .section_tagline .sizzle_hint { right: calc(100% + 0.375rem); height: 1.75rem; padding: 0 0.65rem; font-size: 0.6875rem; }
}
@media (prefers-reduced-motion: reduce) {
  .section_tagline.sz-hint .sizzle_sound::after { animation: none; opacity: 0; }
  .section_tagline .sizzle_hint, .section_tagline.sz-hint-label .sizzle_hint { transition: none; transform: translateY(-50%); }
}

/* ---- v35.44 (Weston): the WJP self-portrait in the client logo bar had no
   dark version (dark ink on the dark bar). It is transparent line art, so it
   takes the same light treatment as the other logos in dark mode. Light
   mode is unchanged. */
html[data-theme="dark"] .logos_image.wjp_logo-custom { filter: brightness(0) invert(0.95); }

/* ---- v35.54 Pricing pair (Alt Design) ---------------------------------------
   Two equal cards, centered and narrower than the old three-up. Each card is
   a subgrid over the same five rows (name, price, line, button, list) so the
   prices, lines and buttons stay level even when a line wraps. Stacked on
   phones with On Demand first (source order).                              */
.section_pricing .heading-style-h1,
.section_pricing .pricing_intro { text-align: center; margin-left: auto; margin-right: auto; }
.section_pricing .pricing_grid { max-width: 1080px; margin-left: auto; margin-right: auto; grid-template-rows: repeat(5, auto); }
.section_pricing .pricing_grid > .pricing_card { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: subgrid; grid-row: span 5; row-gap: 0; align-content: start; }
.section_pricing .pricing_card > .pricing_list { align-self: start; }
.section_pricing .pricing_card > .pricing_line { align-self: start; }
.section_pricing .pricing_flat { font-size: 0.4em; font-weight: 700; letter-spacing: 0; }
.section_pricing .pricing_note { max-width: 1080px; margin-left: auto; margin-right: auto; text-align: center; }
@media (max-width: 767px) {
  .section_pricing .pricing_grid { grid-template-rows: none; }
  .section_pricing .pricing_grid > .pricing_card { grid-template-rows: none; grid-row: auto; display: flex; }
}

/* ---- v35.59 Awards strip (Weston) -------------------------------------------
   Reuses the hero client strip's marquee (.client_logo-bar .container_logos,
   untitled-marquee, same .logo_wrapper and .logos_image sizes, same gaps).
   Each track holds the five logos three times; the duration is scaled to the
   track width so it moves at the client strip's speed (55s for its track,
   40s at 479px and below). No bar fill: it sits on the section background.
   PNG logos keep their ratio (object-fit). Dark mode uses the shared
   .logos_image filter. Reduced motion: one static centered row.           */
.section_awards { overflow: hidden; }
.section_awards .awards_bar { margin: 0 !important; background-color: transparent !important; justify-content: flex-start; overflow: hidden !important; }
.section_awards .awards_track { animation-duration: var(--awards-dur, 48.5s); }
.section_awards .logos_image.awards_logo { object-fit: contain; }
@media screen and (max-width: 479px) {
  .section_awards .awards_track { animation-duration: var(--awards-dur-sm, 35.3s); }
}
@media (prefers-reduced-motion: reduce) {
  .section_awards .awards_bar { justify-content: center; }
  .section_awards .awards_track { animation: none !important; transform: none !important; min-width: 0 !important; width: auto; flex: 0 1 auto; flex-wrap: wrap; justify-content: center; padding-left: 0; padding-right: 0; }
  .section_awards .awards_track[aria-hidden="true"],
  .section_awards .awards_track > .logo_wrapper[aria-hidden="true"] { display: none; }
}
@media (prefers-reduced-motion: reduce) and (max-width: 767px) {
  .section_awards .awards_track { column-gap: 1rem; row-gap: 0; padding-top: 1rem !important; padding-bottom: 1rem !important; }
  .section_awards .awards_track > .logo_wrapper { width: 7rem; height: 4rem; }
}
html[data-theme="dark"] .section_awards.background-color-graytrue25 { background-color: #060c21; }

/* ---- v35.60 hero wordmark loop (Weston) -------------------------------------
   hero-loop.js draws the looping "WJP Studio." in canvas.hero_loop inside the
   h1 (absolute, so no layout shift; the real text stays in the DOM and is only
   made transparent while the canvas is drawing). Light and dark follow
   html[data-theme]. Reduced motion or no JS: the plain text, as before.
   Night layer (.hero_night): the lights-off scene (lights-on in dark) flips
   the hero. It sits under the name, the shade and the logo bar; the bar is
   dimmed by an overlay (--night, set by the script on the header) so its
   marquee keeps running. The wrapper fades with the name like the h1 does.   */
.hero_stack .hero_wordmark { position: relative; }
html.alt-loop-pre .hero_wordmark-text, html.alt-loop-on .hero_wordmark-text { color: transparent !important; }
.hero_loop { position: absolute; left: 0; top: 0; display: none; pointer-events: none; }
html.alt-loop-on .hero_loop { display: block; }
.hero_night { display: none; }
html.alt-loop-on .hero_night { display: block; position: absolute; inset: 0; z-index: 1; pointer-events: none; }
html.alt-loop-on .hero_night-in { position: absolute; inset: 0; background-color: #060c21; opacity: 0; }
html.alt-loop-on[data-theme="dark"] .hero_night-in { background-color: #fcfcfc; }
html.alt-loop-on.hm-cv .hero_night { opacity: var(--cv-name-o, 1); will-change: opacity; }
html.alt-loop-on.hm-simple .hero_night { opacity: 1; transition: opacity 0.4s ease; }
html.alt-loop-on.hm-simple.hm-s-out .hero_night { opacity: 0; }
html.alt-loop-on .section_header > .client_logo-bar::after {
  content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background-color: #030713; opacity: calc(var(--night, 0) * 0.88);
}
html.alt-loop-on[data-theme="dark"] .section_header > .client_logo-bar::after { background-color: #f5f5f7; }
/* nav over the hero while the lights are flipped: the script supplies --ui */
html.alt-night-ui .navbar.hm-nav-top:not(.hm-nav-in) :is(.nav-link-2, .theme_toggle),
html.alt-night-ui .navbar.hm-nav-top:not(.hm-nav-in) :is(.nav-link-2, .theme_toggle):hover { color: var(--ui) !important; transition: none !important; }
html.alt-night-ui .scroll_cue--top { color: var(--ui); }
@media (prefers-reduced-motion: reduce) {
  .hero_loop, .hero_night { display: none !important; }
  html .hero_wordmark-text { color: inherit !important; }
}

/* v35.62: the hero scroll chevron waits for the first converge to finish (opacity and visibility, no layout change); hero-loop.js adds .alt-cue-on. Reduced motion shows it at once. */
@media (prefers-reduced-motion: no-preference) {
  html.alt-loop-pre:not(.alt-cue-on) .scroll_cue--top, html.alt-loop-on:not(.alt-cue-on) .scroll_cue--top { opacity: 0 !important; visibility: hidden; pointer-events: none; }
  html.alt-cue-on .scroll_cue--top { animation: alt-cue-in 0.6s ease; }
}
@keyframes alt-cue-in { from { opacity: 0; } }

/* v35.63: the period is one bouncing ball (word-ball.js). Inactive periods are grey: they keep the word colour, so the
   faded word's own 0.16 opacity greys them. The active word's period is the same grey (a fixed 0.16 alpha, since its word is
   at full opacity), and the one the ball sits on is hidden by colour only (the '.' stays in the text). Only the ball is navy
   (dark mode: the word colour). Transform and opacity only. Reduced motion: no ball, the static periods stay. */
.section_words .container-large { position: relative; }
.words_ball { position: absolute; left: 0; top: 0; display: block; white-space: nowrap; pointer-events: none; z-index: 2; color: #060c21; opacity: 0; will-change: transform, opacity; }
html[data-theme="dark"] .words_ball { color: #f2f3f7; }
html:not(.wb-on) .words_ball { display: none; }
html.wb-on .words_dot { transition: color 0.25s ease-out; }
html.wb-on .words_item.is-active .words_dot { color: rgba(6, 12, 33, 0.16); }
html[data-theme="dark"].wb-on .words_item.is-active .words_dot { color: rgba(242, 243, 247, 0.16); }
html.wb-on .words_item .words_dot.wb-under, html[data-theme="dark"].wb-on .words_item .words_dot.wb-under { color: transparent; transition: none; }

/* v35.63: the footer "The Audit" link is gone (the /audit page itself is untouched). The name and the copyright stay centred, with the copyright closer under the name. */
.section_the-faqs .faq_end-credit { margin-top: 1rem !important; }

/* v35.64: night to tagline handoff, light theme. The lights-off scene is navy, the tagline slide is navy, and the layer used to fade
   out with the name (and ease out over 0.4s under 1280px) while the shade was only starting to fade in, so the hero flashed light
   between the two. While the night scene is on (html.alt-night, set by hero-loop.js) the navy layer now stays at full opacity;
   the shade fades in over it, so the background goes dark once and never lightens. The layer is the same navy as the shade, so it is
   invisible once the shade is full. Not night: unchanged. Dark theme (lights-on is light): unchanged, it already goes light to dark once. */
html.alt-loop-on.alt-night:not([data-theme="dark"]) .hero_night { opacity: 1 !important; }
/* v35.64: while the links fade out after the hero is gone (hm-nav-top is already off), they keep the night colour for a moment (hero-loop.js holds alt-night-ui). */
html.alt-night-ui .navbar:not(.hm-nav-in) :is(.nav-link-2, .theme_toggle),
html.alt-night-ui .navbar:not(.hm-nav-in) :is(.nav-link-2, .theme_toggle):hover { color: var(--ui) !important; transition: none !important; }

/* ==== v35.67 whole-site motion, v35.72 pass 2: the period is the guide (Weston's notes, Nov 11) ====
   One pen and one period. Every moment runs both ways with the scroll. Everything ends in a static, finished state:
   with no JS or with reduced motion the marks, underlines and periods are simply there.
   html.pg-on (site-motion.js, motion allowed) arms the hidden start states.      */

/* v35.72: beside the steps the story starts level with Kickoff and stays in view under the nav while the steps scroll past. */
@media (min-width: 992px) {
  .section_the-how .process_wrapper-left { align-self: stretch; align-items: flex-start; }
  .section_the-how .how_story { position: sticky; top: 8.25rem; max-width: 33.75rem; }
}

/* What we do: six single-stroke marks, band ink, no fills. When a period lands on the tile's word the scroll draws the mark
   (site-motion.js writes the stroke offset), and scrolling back up unwinds it. */
.section_services .offer_mark { display: block; flex: none; width: 3rem; height: 3rem; margin: 0 0 1.5rem; color: #fff; overflow: visible; }
.section_services .offer_mark path { fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
html.pg-on .section_services .offer_mark path { stroke-dasharray: 1; stroke-dashoffset: 1; opacity: 0; }
@media (max-width: 767px) { .section_services .offer_mark { width: 2.5rem; height: 2.5rem; margin-bottom: 1.25rem; } }

/* The Pricing: lean. Hover or focus one plan and the other steps back (headline ink to 60%, secondary to 80%, which keeps
   the dimmed text above AA on the card). Desktop pointers only. Prices and buttons never animate. 180 ms out, 240 ms back. */
@media (hover: hover) and (min-width: 768px) {
  .section_pricing .pricing_card :is(.pricing_name, .pricing_amount, .pricing_line, .pricing_list) { transition: opacity 0.24s ease; }
  .section_pricing .pricing_grid:has(.pricing_card:hover) .pricing_card:not(:hover) :is(.pricing_name, .pricing_amount),
  .section_pricing .pricing_grid:has(.pricing_card:focus-within) .pricing_card:not(:focus-within):not(:hover) :is(.pricing_name, .pricing_amount) { opacity: 0.6; transition-duration: 0.18s; }
  .section_pricing .pricing_grid:has(.pricing_card:hover) .pricing_card:not(:hover) :is(.pricing_line, .pricing_list),
  .section_pricing .pricing_grid:has(.pricing_card:focus-within) .pricing_card:not(:focus-within):not(:hover) :is(.pricing_line, .pricing_list) { opacity: 0.8; transition-duration: 0.18s; }
}


/* The FAQs: one at a time (main.js). The sign is a plus whose upright stroke lies down into a minus (200 ms); the panel
   opens over 280 ms and the answer inks in 160 ms, starting 100 ms in. The old chevron is hidden, not removed. */
.section_the-faqs .the-faqs_icon-wrapper,
.section_the-faqs .the-faqs_component_accordion.is-open .the-faqs_icon-wrapper { transform: none; transition: none; }
.section_the-faqs .the-faqs_icon-wrapper .icon-embed-small { position: relative; }
.section_the-faqs .the-faqs_icon-wrapper .icon-embed-small svg { display: none; }
.section_the-faqs .the-faqs_icon-wrapper .icon-embed-small::before,
.section_the-faqs .the-faqs_icon-wrapper .icon-embed-small::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 1rem; height: 2px; margin: -1px 0 0 -0.5rem;
  border-radius: 1px; background-color: currentColor;
}
.section_the-faqs .the-faqs_icon-wrapper .icon-embed-small::after { transform: rotate(90deg); transition: transform 0.2s cubic-bezier(0.45, 0, 0.25, 1); }
.section_the-faqs .the-faqs_component_accordion.is-open .icon-embed-small::after { transform: rotate(0deg); }
.section_the-faqs .the-faqs_answer {
  display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: 0fr; visibility: hidden;
  transition: grid-template-rows 0.28s cubic-bezier(0.45, 0, 0.25, 1), visibility 0s linear 0.28s;
}
.section_the-faqs .the-faqs_answer > * { min-height: 0; overflow: hidden; opacity: 0; transition: opacity 0.16s ease; }
.section_the-faqs .the-faqs_answer > .margin-bottom { margin-bottom: 0; padding-bottom: 1.5rem; box-sizing: content-box; }
.section_the-faqs .the-faqs_component_accordion.is-open .the-faqs_answer { grid-template-rows: 1fr; visibility: visible; transition-delay: 0s; }
.section_the-faqs .the-faqs_component_accordion.is-open .the-faqs_answer > * { opacity: 1; transition: opacity 0.16s ease 0.1s; }

/* v35.72 the period is the guide (site-motion.js). One glyph in a page-space layer, under the nav glass. A full stop it has
   not reached yet is faint (like the grey periods of the five words), inked once it has landed there, and hidden only while
   the ball sits on it. The real '.' never leaves the text. */
.pg_layer { position: absolute; left: 0; top: 0; width: 100%; height: 0; overflow: visible; pointer-events: none; z-index: 50; }
.pg_ball { position: absolute; left: 0; top: 0; display: block; margin: 0; padding: 0; font-family: Figtree, system-ui, sans-serif; font-size: 128px; font-weight: 900; line-height: 1; letter-spacing: 0; white-space: nowrap; color: #060c21; opacity: 0; will-change: transform, opacity; pointer-events: none; -webkit-user-select: none; user-select: none; }
html:not(.pg-on) .pg_layer { display: none; }
html.pg-on .pg_dot { opacity: 0.18; }
html.pg-on .pg_dot.pg-inked { opacity: 1; }
html.pg-on .pg_dot.pg-under { opacity: 0; }
html.pg-on .pg_dot.pg-ghost:not(.pg-inked) { opacity: 0; }
/* The Pricing buttons: the ball lands on the button, the button springs and its letters ripple out from the hit. Same ripple on hover. */
.section_pricing .pricing_cta .cta_ls { display: inline-block; white-space: pre; }
.section_pricing .pricing_cta .cta_l { display: inline-block; white-space: pre; }
html.pg-on .section_pricing .pricing_cta { transform-origin: 50% 100%; }
html.pg-on .section_pricing .pricing_cta.is-ripple .cta_l { animation: cta-hop 0.36s cubic-bezier(0.3, 0, 0.3, 1) both; }
@keyframes cta-hop { 0%, 100% { transform: none; } 40% { transform: translate3d(0, -0.32em, 0); } }

@media (prefers-reduced-motion: reduce) {
  .section_services .offer_mark path { stroke-dasharray: none !important; stroke-dashoffset: 0 !important; opacity: 1 !important; transition: none !important; }
  .section_pricing .pricing_card :is(.pricing_name, .pricing_amount, .pricing_line, .pricing_list),
  .section_the-faqs .the-faqs_icon-wrapper .icon-embed-small::after,
  .section_the-faqs .the-faqs_answer, .section_the-faqs .the-faqs_answer > * { transition: none !important; }
  .pg_layer { display: none !important; }
  .pg_dot { opacity: 1 !important; }
  .section_pricing .pricing_cta, .section_pricing .pricing_cta .cta_l { animation: none !important; }
}

/* v35.73 the tagline rocket (rocket.js). A white rocket under the on-demand line, there and rumbling from the moment the
   line shows. The scroll launches it through the top of the screen on one thin trail, and the reel rises into its place.
   Scrolling back up brings it down the same path under a parachute. Everything is read from the scroll position. Flat white shapes, one line weight. Reduced motion and no JS: no rocket. */
.rk { position: fixed; left: 0; top: 0; width: 0; height: 0; z-index: 45; pointer-events: none; opacity: 0; visibility: hidden; --rk-k: 1; }
/* desktop pin: rocket.js writes the line's own opacity. Simple hero: the line fades on .hm-s-out (0.5s ease 0.2s in, 0.3s out); the rocket takes the same class and timing. */
html.hm-simple .rk { transition: opacity 0.3s ease; }
html.hm-simple.hm-s-out .rk { opacity: 1; transition: opacity 0.5s ease 0.2s; }
html:not(.rk-on) .rk { display: none; }
.rk_fly { position: absolute; left: 0; top: 0; will-change: transform; }
.rk_sway { position: absolute; left: 0; top: 0; transform-origin: 0 calc(-90px * var(--rk-k)); }
.rk_body { position: absolute; left: calc(-32px * var(--rk-k)); top: 0; width: calc(64px * var(--rk-k)); height: calc(124px * var(--rk-k)); transform-origin: 50% 74%; }
.rk_ship, .rk_chute { display: block; overflow: visible; }
.rk_ship { width: 100%; height: 100%; }
.rk_chute { position: absolute; left: calc(-60px * var(--rk-k)); top: calc(-99px * var(--rk-k)); width: calc(120px * var(--rk-k)); height: calc(104px * var(--rk-k)); opacity: 0; transform-origin: 50% 100%; }
.rk_canopy { transform-box: fill-box; transform-origin: 50% 100%; }
.rk_fill { fill: #fff; }
.rk_line { fill: none; stroke: #fff; stroke-width: 2.5; stroke-linecap: round; }
.rk_flame { fill: none; stroke: #fff; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; transform-box: fill-box; transform-origin: 50% 0; opacity: 0; }
.rk .rk_flame { opacity: 1; animation: rk-flame 0.22s ease-in-out infinite alternate; }
.rk.is-burn .rk_flame { animation: rk-burn 0.12s ease-in-out infinite alternate; }
.rk.is-chute .rk_flame { opacity: 0; animation: none; }
.rk.is-rumble .rk_body { animation: rk-rumble 0.36s linear infinite; }
.rk_trail { position: absolute; left: 0; top: 0; width: calc(3px * var(--rk-k)); height: 200px; border-radius: 2px; background-color: #fff; transform-origin: 50% 0; opacity: 0; }
@keyframes rk-flame { from { transform: scale(0.9, 0.7); } to { transform: scale(1.05, 1.05); } }
@keyframes rk-burn { from { transform: scale(1.1, 1.9); } to { transform: scale(1.25, 2.6); } }
@keyframes rk-rumble {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg); } 12% { transform: translate3d(-1.5px, 0.5px, 0) rotate(-1.2deg); }
  25% { transform: translate3d(1.5px, -0.5px, 0) rotate(1deg); } 37% { transform: translate3d(-1px, -1px, 0) rotate(-0.8deg); }
  50% { transform: translate3d(1.5px, 0.5px, 0) rotate(1.2deg); } 62% { transform: translate3d(-1.5px, 0, 0) rotate(-1deg); }
  75% { transform: translate3d(1px, 1px, 0) rotate(0.8deg); } 87% { transform: translate3d(-1px, -0.5px, 0) rotate(-0.6deg); }
}
html.rk-on.sz-js.sz-live .section_tagline .sizzle_frame { transform: translate(-50%, calc(-50% + var(--rk-rise, 0px))); }
@media (prefers-reduced-motion: reduce) { .rk { display: none !important; } }

/* ==== v35.73 site motion, pass 3 (Weston's notes, Nov 12) ====================================================
   Everything below is read from the scroll position by site-motion.js, both ways. No timed transitions on anything
   the scroll drives. No JS or reduced motion: every mark, period and panel is simply there, finished. */

/* Five words: the ink of each word follows the period (--wi), not a timed fade. */
html.pg-on.hm-words .section_words .words_item .words_word,
html.pg-on.hm-words .section_words .words_item.is-active .words_word { opacity: var(--wi, 0.16); transition: none; }
html.pg-on .section_words .words_dot.pg-under { color: transparent; }
html.pg-on .section_words .words_dot.pg-left { color: rgba(6, 12, 33, 0.16); }
html[data-theme="dark"].pg-on .section_words .words_dot.pg-left { color: rgba(242, 243, 247, 0.16); }

/* Section reveals (main.js marks .reveal): opacity and a small rise from --rv. */
html.pg-on .reveal, html.pg-on .reveal.is-inview {
  opacity: var(--rv, 0); transform: translate3d(0, calc((1 - var(--rv, 0)) * 34px), 0); transition: none; will-change: opacity, transform;
}

/* What we do: the calendar's date squares use a lighter line so six of them fit. */
.section_services .offer_mark path.offer_sq { stroke-width: 2.2; }

/* The How: the row is held while the story plays (how-story.js sets the height and the sticky top). */
.section_the-how .how_pin { position: relative; }
/* the step line: the markers are faint rings; the period rides the line (.how_track-dot) and each marker it reaches becomes a period. No checks. */
html.pg-on.hm-howdot .section_the-how .how_step-dot { transition: none; }
html.pg-on.hm-howdot .section_the-how .how_step-dot.is-period,
html[data-theme="dark"].pg-on.hm-howdot .section_the-how .how_step-dot.is-period {
  z-index: 2; background-color: #060c21; border-color: #060c21; box-shadow: 0 0 0 1px #060c21; background-image: none;
}
html[data-theme="dark"].pg-on.hm-howdot .section_the-how .how_step-dot.is-period { background-color: #f2f3f7; border-color: #f2f3f7; box-shadow: 0 0 0 1px #f2f3f7; }
html.hm-howdot .section_the-how .how_step-dot.is-done,
html[data-theme="dark"].hm-howdot .section_the-how .how_step-dot.is-done { background-color: #060c21; border-color: #060c21; background-image: none; transform: scale(1.22); }
html[data-theme="dark"].hm-howdot .section_the-how .how_step-dot.is-done { background-color: #f2f3f7; border-color: #f2f3f7; }
html.pg-on.hm-howdot .section_the-how .how_track-dot,
html[data-theme="dark"].pg-on.hm-howdot .section_the-how .how_track-dot {
  display: block; left: calc(0.25rem - 5px); top: -5.5px; width: 11px; height: 11px; border: 0; background-color: #060c21; opacity: 0; z-index: 3;
  transform: translate3d(0, 0, 0); transform-origin: 50% 50%;
}
html[data-theme="dark"].pg-on.hm-howdot .section_the-how .how_track-dot { background-color: #f2f3f7; }

/* The How story (how-story.js): the Requests interface, drawn at 540 x 520 and scaled to the column. Portal tokens. */
.section_the-how .how_story {
  position: relative; width: 100%; max-width: 33.75rem; aspect-ratio: 540 / 520; margin-inline: auto;
  --hs-bg: #f5f5f7; --hs-solid: #fcfcfc; --hs-ink: #060c21; --hs-ink2: #4b5166; --hs-ink3: #86868b;
  --hs-glass: rgba(255, 255, 255, 0.66); --hs-edge: rgba(255, 255, 255, 0.9); --hs-card: #ededf1; --hs-field: rgba(6, 12, 33, 0.06);
  --hs-line: rgba(6, 12, 33, 0.09); --hs-line2: rgba(6, 12, 33, 0.2); --hs-btn: #060c21; --hs-btnfg: #fcfcfc;
  --hs-sheet: rgba(250, 250, 252, 0.9); --hs-scrim: rgba(245, 245, 247, 0.5); --hs-green: #2fd158; --hs-yellow: #ffcc00;
  --hs-shadow: 0 16px 48px rgba(6, 12, 33, 0.09); --hs-sheet-shadow: 0 40px 96px rgba(6, 12, 33, 0.2);
}
html[data-theme="dark"] .section_the-how .how_story {
  --hs-bg: #0e1328; --hs-solid: #171d31; --hs-ink: #f2f3f7; --hs-ink2: #c4c7d0; --hs-ink3: #a3a8b8;
  --hs-glass: rgba(23, 29, 49, 0.72); --hs-edge: rgba(242, 243, 247, 0.1); --hs-card: #232a44; --hs-field: rgba(242, 243, 247, 0.07);
  --hs-line: rgba(242, 243, 247, 0.1); --hs-line2: rgba(242, 243, 247, 0.24); --hs-btn: #f2f3f7; --hs-btnfg: #060c21;
  --hs-sheet: rgba(23, 29, 49, 0.92); --hs-scrim: rgba(6, 12, 33, 0.56);
  --hs-shadow: 0 16px 48px rgba(0, 0, 0, 0.3); --hs-sheet-shadow: 0 40px 96px rgba(0, 0, 0, 0.5);
}
/* the dark theme recolours every span, div and p in this section; inside the story they inherit the portal ink instead */
html .section_the-how .how_story .hs_stage :where(span, div, p, i) { color: inherit; }
html .section_the-how .how_story .hs_stage { position: absolute; left: 0; top: 0; width: 540px; height: 520px; transform-origin: 0 0; font-family: Figtree, system-ui, sans-serif; color: var(--hs-ink); line-height: 1.2; text-align: left; pointer-events: none; -webkit-user-select: none; user-select: none; }
html .section_the-how .how_story .hs_stage i { font-style: normal; display: block; }
html .section_the-how .how_story .hs_win { position: absolute; inset: 0; border-radius: 28px; background: var(--hs-bg); border: 1px solid var(--hs-line); box-shadow: var(--hs-shadow); overflow: hidden; }
html .section_the-how .how_story .hs_bar { position: absolute; left: 24px; right: 18px; top: 16px; height: 42px; display: flex; align-items: center; justify-content: space-between; }
html .section_the-how .how_story .hs_brand { font-size: 20px; font-weight: 900; letter-spacing: -0.01em; }
html .section_the-how .how_story .hs_btn { display: inline-flex; align-items: center; height: 38px; padding: 0 17px; border-radius: 999px; background: var(--hs-btn); color: var(--hs-btnfg); font-size: 13.5px; font-weight: 600; white-space: nowrap; box-shadow: 0 4px 12px rgba(6, 12, 33, 0.18), inset 0 1px 0 rgba(255, 255, 255, 0.18); will-change: transform; }
html .section_the-how .how_story .hs_btn--quiet { background: var(--hs-field); color: var(--hs-ink); box-shadow: none; }
html .section_the-how .how_story .hs_col { position: absolute; top: 76px; width: 164px; height: 428px; box-sizing: border-box; border-radius: 22px; background: var(--hs-glass); border: 1px solid var(--hs-edge); box-shadow: 0 8px 28px rgba(6, 12, 33, 0.05); }
html .section_the-how .how_story .hs_col[data-k="req"] { left: 14px; }
html .section_the-how .how_story .hs_col[data-k="work"] { left: 188px; }
html .section_the-how .how_story .hs_col[data-k="done"] { left: 362px; }
html .section_the-how .how_story .hs_colh { display: flex; align-items: center; gap: 9px; padding: 17px 14px 0; font-size: 17px; font-weight: 800; letter-spacing: -0.01em; white-space: nowrap; }
html .section_the-how .how_story .hs_dot { width: 10px; height: 10px; border-radius: 50%; flex: none; box-sizing: border-box; }
html .section_the-how .how_story .hs_dot--req { border: 2px solid var(--hs-ink2); }
html .section_the-how .how_story .hs_dot--work { background: var(--hs-yellow); box-shadow: 0 0 0 3px rgba(255, 204, 0, 0.28); }
html .section_the-how .how_story .hs_dot--done { background: var(--hs-green); box-shadow: 0 0 0 3px rgba(47, 209, 88, 0.26); }
html .section_the-how .how_story .hs_card { position: absolute; left: 0; top: 0; width: 144px; box-sizing: border-box; padding: 13px 12px 12px; border-radius: 14px; background: var(--hs-card); opacity: 0; transform-origin: 50% 50%; will-change: transform, opacity; }
html .section_the-how .how_story .hs_card-t { display: block; font-size: 15.5px; font-weight: 600; line-height: 1.26; }
html .section_the-how .how_story .hs_card-m { display: flex; align-items: center; justify-content: space-between; margin-top: 10px; font-size: 12px; font-weight: 500; color: var(--hs-ink3); height: 17px; }
html .section_the-how .how_story .hs_card-left::before { content: "48h left"; }
html .section_the-how .how_story .hs_card.is-work .hs_card-left::before { content: "47h left"; }
html .section_the-how .how_story .hs_ring { width: 16px; height: 16px; border-radius: 50%; border: 1.5px dashed var(--hs-line2); box-sizing: border-box; }
html .section_the-how .how_story .hs_ok { width: 17px; height: 17px; border-radius: 50%; background: var(--hs-green); color: #fff; display: flex !important; align-items: center; justify-content: center; }
html .section_the-how .how_story .hs_ok svg { display: block; width: 68%; height: 68%; }
html .section_the-how .how_story .hs_card .hs_card-donel, html .section_the-how .how_story .hs_card .hs_ok { display: none !important; }
html .section_the-how .how_story .hs_card.is-done .hs_card-left, html .section_the-how .how_story .hs_card.is-done .hs_ring { display: none; }
html .section_the-how .how_story .hs_card.is-done .hs_card-donel { display: inline !important; }
html .section_the-how .how_story .hs_card.is-done .hs_ok { display: flex !important; }
html .section_the-how .how_story .hs_scrim { position: absolute; inset: 0; background: var(--hs-scrim); -webkit-backdrop-filter: blur(5px); backdrop-filter: blur(5px); opacity: 0; }
html .section_the-how .how_story .hs_sheet { position: absolute; left: 36px; right: 36px; top: 30px; bottom: 30px; box-sizing: border-box; padding: 24px 26px; border-radius: 26px; background: var(--hs-sheet); border: 1px solid var(--hs-edge); box-shadow: var(--hs-sheet-shadow), inset 0 1px 0 rgba(255, 255, 255, 0.4); opacity: 0; visibility: hidden; transform-origin: 50% 60%; will-change: transform, opacity; }
html .section_the-how .how_story .hs_sheet-h { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
html .section_the-how .how_story .hs_sheet-t { font-size: 27px; font-weight: 900; letter-spacing: -0.02em; line-height: 1.12; }
html .section_the-how .how_story .hs_sheet-t--card { font-size: 22px; padding-top: 5px; }
html .section_the-how .how_story .hs_sheet--card { bottom: 132px; }
html .section_the-how .how_story .hs_x { width: 30px; height: 30px; border-radius: 50%; background: var(--hs-field); display: flex !important; align-items: center; justify-content: center; flex: none; }
html .section_the-how .how_story .hs_x svg { display: block; width: 14px; height: 14px; }
html .section_the-how .how_story .hs_acts { display: flex; align-items: center; gap: 8px; flex: none; }
html .section_the-how .how_story .hs_acts .hs_btn { height: 34px; padding: 0 15px; font-size: 12.5px; }
html .section_the-how .how_story .hs_field { position: relative; margin-top: 14px; box-sizing: border-box; border-radius: 14px; background: var(--hs-field); border: 1.5px solid transparent; padding: 13px 16px; font-size: 15px; font-weight: 600; line-height: 1.3; }
html .section_the-how .how_story .hs_field--title { height: 48px; white-space: nowrap; }
html .section_the-how .how_story .hs_field--note { height: 96px; padding-top: 12px; font-size: 14.5px; font-weight: 500; line-height: 1.45; }
html .section_the-how .how_story .hs_field.on { border-color: var(--hs-ink); background: var(--hs-solid); }
html .section_the-how .how_story .hs_ph { color: var(--hs-ink3); }
html .section_the-how .how_story .hs_field.has .hs_ph { display: none; }
html .section_the-how .how_story .hs_stage .hs_caret { display: none; width: 1.5px; height: 1.15em; background: var(--hs-ink); vertical-align: -0.2em; margin: 0 1px; }
html .section_the-how .how_story .hs_stage .hs_field.on .hs_caret { display: inline-block; }
html .section_the-how .how_story .hs_drop { margin-top: 12px; height: 92px; box-sizing: border-box; border-radius: 14px; border: 1.5px dashed var(--hs-line2); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px; color: var(--hs-ink2); font-size: 13.5px; font-weight: 500; }
html .section_the-how .how_story .hs_drop svg { display: block; width: 20px; height: 20px; }
html .section_the-how .how_story .hs_sheet-f { position: absolute; right: 26px; bottom: 24px; }
html .section_the-how .how_story .hs_meta { display: flex; align-items: center; gap: 12px; margin-top: 14px; font-size: 13px; font-weight: 500; color: var(--hs-ink2); }
html .section_the-how .how_story .hs_pill { display: inline-flex; align-items: center; gap: 7px; height: 28px; padding: 0 12px; border-radius: 999px; border: 1px solid var(--hs-line2); font-weight: 600; color: var(--hs-ink); will-change: transform; }
html .section_the-how .how_story .hs_pill-dot { width: 8px; height: 8px; box-shadow: none; }
html .section_the-how .how_story .hs_pill-b, html .section_the-how .how_story .hs_meta-b { display: none; }
html .section_the-how .how_story .hs_sheet--card.is-done .hs_pill-a, html .section_the-how .how_story .hs_sheet--card.is-done .hs_meta-a { display: none; }
html .section_the-how .how_story .hs_sheet--card.is-done .hs_pill-b, html .section_the-how .how_story .hs_sheet--card.is-done .hs_meta-b { display: inline; }
html .section_the-how .how_story .hs_sheet--card.is-done .hs_pill-dot { background: var(--hs-green); }
html .section_the-how .how_story .hs_ok--big { display: inline-flex !important; width: 21px; height: 21px; margin-left: 9px; vertical-align: -2px; transform: scale(0); }
html .section_the-how .how_story .hs_body { margin: 18px 0 0; max-width: 360px; font-size: 14.5px; font-weight: 500; line-height: 1.5; color: var(--hs-ink2); }
html .section_the-how .how_story .hs_rule { height: 1px; margin-top: 22px; background: var(--hs-line); }
html .section_the-how .how_story .hs_docs { margin-top: 16px; font-size: 16px; font-weight: 800; letter-spacing: -0.01em; }
html .section_the-how .how_story .hs_docs-n { margin-top: 6px; font-size: 12.5px; color: var(--hs-ink3); }
html .section_the-how .how_story .hs_toast { position: absolute; left: 50%; bottom: 54px; display: flex; align-items: center; gap: 8px; padding: 9px 16px; border-radius: 999px; background: var(--hs-solid); border: 1px solid var(--hs-line); box-shadow: 0 10px 30px rgba(6, 12, 33, 0.16); font-size: 13.5px; font-weight: 600; opacity: 0; white-space: nowrap; }
html .section_the-how .how_story .hs_toast::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--hs-green); }
html .section_the-how .how_story .hs_cur { position: absolute; left: 0; top: 0; width: 22px; height: 22px; margin: -3px 0 0 -5px; transform-origin: 5px 3px; overflow: visible; opacity: 0; will-change: transform; filter: drop-shadow(0 2px 3px rgba(6, 12, 33, 0.25)); }
html .section_the-how .how_story .hs_cur path { fill: #060c21; stroke: #fff; stroke-width: 1.6; stroke-linejoin: round; }
html .section_the-how .how_story .hs_stage .hs_tap { position: absolute; left: 0; top: 0; width: 26px; height: 26px; margin: -13px 0 0 -13px; border-radius: 50%; border: 2px solid var(--hs-ink); box-sizing: border-box; opacity: 0; }

/* The Pricing buttons: the scroll writes the squash and the letter ripple, so nothing here may ease them. */
html.pg-on .section_pricing .pricing_cta { transition-property: background-color, color, border-color; will-change: transform; }
html.pg-on .section_pricing .pricing_cta .cta_l { will-change: transform; }

/* The FAQs: each plus sign turns as its row crosses the screen (--spin). An open one lies flat as a minus. */
html.pg-on .section_the-faqs .the-faqs_icon-wrapper .icon-embed-small { transform: rotate(var(--spin, 0deg)); will-change: transform; }
html.pg-on .section_the-faqs .the-faqs_component_accordion.is-open .icon-embed-small { transform: rotate(0deg); }
html.pg-on .section_the-faqs .the-faqs_icon-wrapper .icon-embed-small.is-easing { transition: transform 0.28s cubic-bezier(0.45, 0, 0.25, 1); }

/* The glass elevator under the copyright (elevator.js). One ink, one line weight, a glass cab with the period inside. */
.section_the-faqs .faq_end .lift {
  display: inline-flex; flex-direction: column; align-items: center; gap: 0.625rem; margin-top: 2.5rem; padding: 0.25rem 0.75rem 0.5rem;
  color: #060c21; text-decoration: none; cursor: pointer; -webkit-tap-highlight-color: transparent; border-radius: 1rem;
}
html[data-theme="dark"] .section_the-faqs .faq_end .lift { color: #f2f3f7; }
.lift:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }
.lift_shaft { position: relative; display: block; width: 6.5rem; height: 6.125rem; }
.lift_cab { position: absolute; left: 50%; top: 0; width: 4.5rem; height: 5.9rem; margin-left: -2.25rem; overflow: hidden; display: block; }
.lift svg, .lift_fly svg { display: block; width: 4.5rem; height: 7rem; overflow: visible; fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.lift_cab svg { translate: 0 calc((1 - var(--lift-in, 1)) * 96%); }
.lift_glass { fill: currentColor; fill-opacity: 0.06; }
.lift_glint { opacity: 0.45; }
.lift_knob, .lift_rider { fill: currentColor; stroke: none; }
.lift_rider { opacity: 0; }
html:not(.pg-on) .lift_rider, .lift.has-rider .lift_rider, .lift_fly .lift_rider { opacity: 1; }
.lift_fly.is-empty .lift_rider { opacity: 0; transition: opacity 0.25s ease; }
.lift_flames { fill: currentColor; stroke: none; opacity: 0; transform-box: fill-box; transform-origin: 50% 0; }
.lift_fly.is-burn .lift_flames { opacity: 1; animation: lift-burn 0.1s ease-in-out infinite alternate; }
.lift_floor { position: absolute; left: 0; right: 0; top: 5.9rem; height: 3px; margin-top: -1px; border-radius: 2px; background-color: currentColor; display: block; }
.lift_label { font-family: Figtree, system-ui, sans-serif; font-size: 0.9375rem; font-weight: 700; line-height: 1.3; letter-spacing: 0; }
.lift_sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.lift.is-ready .lift_cab svg { animation: lift-bob 1.9s ease-in-out infinite alternate; }
.lift.is-ready:hover .lift_cab svg, .lift.is-ready:focus-visible .lift_cab svg { animation-duration: 0.32s; }
.lift.is-away .lift_cab svg { visibility: hidden; }
.lift_fly { position: fixed; left: 0; top: 0; z-index: 60; pointer-events: none; color: #fff; mix-blend-mode: difference; transform-origin: 50% 84%; will-change: transform, opacity; }
@keyframes lift-bob { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(0, -5px, 0); } }
@keyframes lift-burn { from { transform: scaleY(0.75); } to { transform: scaleY(1.5); } }
@media (prefers-reduced-motion: reduce) {
  .lift.is-ready .lift_cab svg { animation: none !important; }
  .lift_cab svg { translate: none !important; }
  .lift_rider { opacity: 1 !important; }
  .lift_fly { display: none !important; }
}

/* v35.74 (Weston): on desktop the How story sits centered on the same horizontal line as the steps beside it. */
@media (min-width: 992px) {
  .section_the-how .process_wrapper-left { align-self: center; align-items: center; }
  .section_the-how .how_story { position: relative; top: auto; }
}

/* v35.75 (Weston): the rocket rumbles about half as hard on its pad. */
.rk.is-rumble .rk_body { animation: rk-rumble2 0.5s linear infinite; }
@keyframes rk-rumble2 {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg); } 12% { transform: translate3d(-0.7px, 0.25px, 0) rotate(-0.5deg); }
  25% { transform: translate3d(0.7px, -0.25px, 0) rotate(0.45deg); } 37% { transform: translate3d(-0.5px, -0.5px, 0) rotate(-0.35deg); }
  50% { transform: translate3d(0.7px, 0.25px, 0) rotate(0.5deg); } 62% { transform: translate3d(-0.7px, 0, 0) rotate(-0.45deg); }
  75% { transform: translate3d(0.5px, 0.5px, 0) rotate(0.35deg); } 87% { transform: translate3d(-0.5px, -0.25px, 0) rotate(-0.25deg); }
}

/* v35.76 (Weston): no drawings in the five pillars. */
.section_services .offer_mark { display: none !important; }

/* Site fix 3: services are already visible; the period tracks remain independent. */
html .section_services.reveal, html .section_services .reveal,
html.pg-on .section_services .reveal.is-inview {
  opacity: 1; transform: none; transition: none; will-change: auto;
}
/* Two sliding leaves. A narrow slit keeps only a hint of the passenger visible. */
.lift_door { transform-box: view-box; transition: transform 480ms cubic-bezier(.45,0,.25,1); }
.lift_door--left { transform: translateX(calc(-19px * var(--door-open, 1))); }
.lift_door--right { transform: translateX(calc(19px * var(--door-open, 1))); }
.lift_rider { clip-path: inset(0 calc((1 - var(--door-open, 1)) * 44%) 0 calc((1 - var(--door-open, 1)) * 44%)); transform-box: fill-box; transition: clip-path 480ms cubic-bezier(.45,0,.25,1); }
.lift.has-rider { --door-open: 0; }
.lift_fly .lift_door, .lift_fly .lift_rider { transition: none; }
.lift_fly { mix-blend-mode: normal; }
.lift_passenger { position: fixed; left: 0; top: 0; z-index: 61; pointer-events: none; line-height: 1; transform-origin: 50% 50%; }
html .pg_dot.lift_landed { color: inherit !important; }
@media (prefers-reduced-motion: reduce) {
  .lift_door, .lift_rider { transition: none; }
  .lift_passenger { display: none; }
}

/* FAQ theme fills apply to its icons, while the cab remains line art. */
html .section_the-faqs .lift svg path, html .lift_fly svg path { fill: none !important; }

/* WJP Studio wordmark and approved About layout. Live motion selectors stay intact. */
@font-face{font-family:Figtree;src:url('/assets/figtree-black.ttf') format('truetype');font-style:normal;font-weight:900;font-display:swap}
.logo_wordmark,.hero_wordmark,.faq_end-name{font-weight:900;letter-spacing:.015em}
.studio-footer-principal{font-size:12px;line-height:1.6;margin:14px 0;color:inherit;opacity:.7}
.studio-about{max-width:1280px;padding:100px 40px;margin:auto;display:grid;grid-template-columns:1.2fr 1fr;gap:100px;align-items:center;color:#060c21}
.studio-about h2{color:inherit;font-size:64px;line-height:1.05;font-weight:900;letter-spacing:-.025em;margin:0 0 32px}
.studio-about .eyebrow{font-size:20px;margin:0 0 16px;font-weight:600}
.studio-about p{font-size:22px;line-height:1.55;margin:0}
.studio-portrait-slot{width:100%;aspect-ratio:480/469;max-height:570px;display:flex;align-items:center;justify-content:center}
.studio-portrait-frame{width:70%;box-sizing:border-box}
.studio-portrait{position:relative;display:block;width:100%;aspect-ratio:480/469}
.studio-portrait canvas{position:absolute;display:block}
html[data-theme="dark"] .studio-about{color:#f2f3f7}
/* Preserve the original padded image height: 48 * (1 - 469 / 480) = 1.1px. */
html[data-theme="dark"] .studio-portrait-slot{padding-block:.55px;box-sizing:content-box}
html[data-theme="dark"] .studio-portrait-frame{background:#fcfcfc;border-radius:16.8px;padding:16.8px}
@media(max-width:767px){.studio-about{padding:56px 24px;grid-template-columns:1fr;gap:40px}.studio-about h2{font-size:42px;margin-bottom:24px}.studio-about p{font-size:19px}.studio-about .eyebrow{font-size:18px}.studio-portrait-slot{max-height:400px}}

/* ==== v36 hero wordmark: "WJP Studio." drawn as SVG (hero-loop.js) ==========================
   The name is the code logo's outlines (Figtree Black) in an inline SVG laid exactly over the live text of
   h1.hero_wordmark; the text stays in the DOM and is only transparent while the SVG is up (html.alt-loop-on,
   same switch as the v35.60 canvas loop, which this replaces; its night layer stays off). Ink is currentColor,
   so light and dark need nothing here. --wm-em is the width of "WJP Studio." in em (was 5.66 for the old
   name), so the name keeps its 62vw / 84vw fit. The script owns the name's exit (the period stamps it flat,
   read from the scroll), so the plain opacity fade is switched off while it runs. Reduced motion or no JS:
   the plain text, as before. */
:root { --wm-em: 5.97; }
/* dark: the name is light ink (the canvas loop used to paint its own colour; the plain text never had one) */
html[data-theme="dark"] .hero_stack .hero_wordmark, html.hm-cv[data-theme="dark"] .hero_stack .hero_wordmark { color: #f2f3f7; }
.hero_wl { position: absolute; left: 0; top: 0; display: none; overflow: visible; pointer-events: none; }
html.alt-loop-on .hero_wl { display: block; }
html.alt-loop-on.hm-cv .hero_stack .hero_wordmark { opacity: 1; }
html.alt-loop-on.hm-simple.hm-s-out .hero_stack .hero_wordmark { opacity: 1; transform: none; visibility: visible; transition: none; }
/* below 1280 the exit is a class trigger: the hero darkens and the line comes in once the name is flat */
html.alt-loop-on.hm-simple.hm-s-out .hero_shade { transition-delay: 0.3s; }
html.alt-loop-on.hm-simple.hm-s-out .section_tagline .tagline_text,
html.alt-loop-on.hm-simple.hm-s-out .rk { transition: opacity 0.5s ease 0.55s; }   /* the rocket keeps the line's timing */
@media (prefers-reduced-motion: reduce) { .hero_wl { display: none !important; } }
