/* JS sets html.js so these only apply when JS is running (graceful fallback). */

  /* Nav — reverted to match the live site exactly.
     The live theme handles everything natively:
       - `.siteheader` is `position: relative; height: 168px` (in normal flow),
         so it scrolls away as the user scrolls down and scrolls back into view
         (with its default tall appearance) when they scroll back to top.
       - `.site-header__fixed` is `position: fixed` (theme default), so the
         visible bar stays pinned at the viewport top at all times. Its
         `z-index: 999` keeps it above page content.
       - `.fixed_border` (the dark left-edge stripe) is `position: fixed;
         height: 100%; z-index: 1002` from the theme — naturally above the nav.
       - The theme's `custom.js` toggles `.stickylogo--show` + `.pt-25` on
         `.site-header__fixed` when scrollTop ≥ 168px, swapping to the
         horizontal logo and shrinking the bar. Reversing them (scrolling back
         to top) restores the default tall nav.
       - `.homepage__content { padding-top: 40px }` from the theme is kept so
         the hero video has the same small breathing space above it as on live.
     No custom CSS or JS needed for any of this — letting the theme run as-is. */

  /* 2) Hero video box — swipes in via clip-path */
  html.js .video-container[data-anim="video"] {
    clip-path: inset(0 100% 0 0);
    -webkit-clip-path: inset(0 100% 0 0);
    transition: clip-path 1100ms cubic-bezier(0.22, 1, 0.36, 1),
                -webkit-clip-path 1100ms cubic-bezier(0.22, 1, 0.36, 1);
    will-change: clip-path;
  }
  html.js .video-container[data-anim="video"].is-revealed {
    clip-path: inset(0 0 0 0);
    -webkit-clip-path: inset(0 0 0 0);
  }

  /* 3) White rectangle border — 4 edges drawn in sequence (top → right → bottom → left)
     mimicking an SVG path-stroke animation. */
  .content-video[data-anim="border"] {
    border: 0 !important; /* disable any static border so only the animated edges show */
    position: relative;
  }
  .content-video[data-anim="border"] > .hero-edge {
    position: absolute;
    background: #fff;
    transition: transform 450ms cubic-bezier(0.22, 1, 0.36, 1);
    will-change: transform;
    pointer-events: none;
  }
  .content-video[data-anim="border"] > .hero-edge--top    { top: 0;    left: 0; right: 0;  height: 1px; transform-origin: left center;   transform: scaleX(0); }
  .content-video[data-anim="border"] > .hero-edge--right  { top: 0;    right: 0; bottom: 0; width: 1px; transform-origin: center top;    transform: scaleY(0); }
  .content-video[data-anim="border"] > .hero-edge--bottom { bottom: 0; left: 0; right: 0;  height: 1px; transform-origin: right center;  transform: scaleX(0); }
  .content-video[data-anim="border"] > .hero-edge--left   { top: 0;    left: 0; bottom: 0; width: 1px;  transform-origin: center bottom; transform: scaleY(0); }
  .content-video[data-anim="border"].is-revealed > .hero-edge--top    { transform: scaleX(1); transition-delay: 350ms;  }
  .content-video[data-anim="border"].is-revealed > .hero-edge--right  { transform: scaleY(1); transition-delay: 700ms;  }
  .content-video[data-anim="border"].is-revealed > .hero-edge--bottom { transform: scaleX(1); transition-delay: 1050ms; }
  .content-video[data-anim="border"].is-revealed > .hero-edge--left   { transform: scaleY(1); transition-delay: 1400ms; }

  /* 4) Hero headline — split into lines by JS, each line slides up from below.
     Headline starts hidden so the un-split fallback text doesn't flash before
     splitH1IntoLines() runs (which is deferred until fonts.ready so the line
     breaks match the loaded Cardo metrics, not the system fallback's). */
  html.js .homepage__content h1[data-anim="lines"] {
    visibility: hidden;
  }
  html.js .homepage__content h1[data-anim="lines"].is-revealed {
    visibility: visible;
  }
  .homepage__content h1[data-anim="lines"] .hero-line {
    display: block;
    overflow: hidden;
    line-height: 1.15;
    padding-bottom: 0.04em; /* prevents descender clipping inside the clip box */
  }
  .homepage__content h1[data-anim="lines"] .hero-line__inner {
    display: block;
    transform: translateY(110%);
    transition: transform 800ms cubic-bezier(0.22, 1, 0.36, 1);
    will-change: transform;
  }
  .homepage__content h1[data-anim="lines"].is-revealed .hero-line__inner {
    transform: translateY(0);
  }
  .homepage__content h1[data-anim="lines"].is-revealed .hero-line:nth-child(1) .hero-line__inner { transition-delay: 1500ms; }
  .homepage__content h1[data-anim="lines"].is-revealed .hero-line:nth-child(2) .hero-line__inner { transition-delay: 1700ms; }
  .homepage__content h1[data-anim="lines"].is-revealed .hero-line:nth-child(3) .hero-line__inner { transition-delay: 1900ms; }
  .homepage__content h1[data-anim="lines"].is-revealed .hero-line:nth-child(4) .hero-line__inner { transition-delay: 2100ms; }

  /* Reduced motion — show everything instantly with no transforms */
  @media (prefers-reduced-motion: reduce) {
    .siteheader[data-anim="nav"],
    .video-container[data-anim="video"],
    .content-video[data-anim="border"] > .hero-edge,
    .homepage__content h1[data-anim="lines"] .hero-line__inner {
      opacity: 1 !important;
      transform: none !important;
      clip-path: none !important;
      -webkit-clip-path: none !important;
      transition: none !important;
    }
    .homepage__content h1[data-anim="lines"] { visibility: visible !important; }
    .content-video[data-anim="border"] { border: 1px solid #fff !important; }
    .content-video[data-anim="border"] > .hero-edge { display: none !important; }
  }

  /* ===== Our Firm slider — two-layer curtain reveal + image zoom-out =====
     Ported from the Redland history-image reveal, recolored gold + black.
     Curtains cover the whole .homepage__firm--slider so Swiper's per-slide
     transforms aren't touched. Gold rides on top and slides up; black sits
     beneath and slides down a beat later; the slide image scales 1.2 → 1.0. */
  html.js .homepage__firm--slider[data-anim="firm"] {
    position: relative;
    /* No overflow:hidden here — that would clip the ::before connector line
       which sits at left:-158px outside the slider's box. The curtains get
       their own clipping container (.firm-curtain-wrap) instead. */
  }
  html.js .homepage__firm--slider[data-anim="firm"] > .firm-curtain-wrap {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    z-index: 3;
  }
  html.js .homepage__firm--slider[data-anim="firm"] .firm-curtain {
    position: absolute;
    inset: 0;
    pointer-events: none;
    transform: translateY(0%);
    transition: transform 0.55s cubic-bezier(.42, 0, .58, 1);
    will-change: transform;
  }
  html.js .homepage__firm--slider[data-anim="firm"] .firm-curtain--gold {
    z-index: 2;
    background: #b38100; /* Berkman gold */
    transition-delay: 0.2s;
  }
  html.js .homepage__firm--slider[data-anim="firm"] .firm-curtain--black {
    z-index: 1;
    background: #000;
    transition-delay: 0.6s;
  }
  html.js .homepage__firm--slider[data-anim="firm"].is-revealed .firm-curtain--gold  { transform: translateY(-110%); }
  html.js .homepage__firm--slider[data-anim="firm"].is-revealed .firm-curtain--black { transform: translateY(100%);  }

  html.js .homepage__firm--slider[data-anim="firm"] .swiper-slide__image,
  html.js .homepage__firm--slider[data-anim="firm"] .mobile_slide {
    transform: scale(1.2);
    transition: transform 0.85s cubic-bezier(.42, 0, .58, 1);
    transition-delay: 0.6s;
    will-change: transform;
  }
  html.js .homepage__firm--slider[data-anim="firm"].is-revealed .swiper-slide__image,
  html.js .homepage__firm--slider[data-anim="firm"].is-revealed .mobile_slide {
    transform: scale(1);
  }

  @media (prefers-reduced-motion: reduce) {
    .homepage__firm--slider[data-anim="firm"] > .firm-curtain { display: none !important; }
    .homepage__firm--slider[data-anim="firm"] .swiper-slide__image,
    .homepage__firm--slider[data-anim="firm"] .mobile_slide {
      transform: none !important;
      transition: none !important;
    }
  }

  /* ===== Our Firm — horizontal connector line (matches live site spec) =====
     The live site renders this as a 158px × 1px black rule sitting just to
     the left of the slider's left edge (`top: 23px; left: -158px`). The local
     stylesheet is missing the rule — re-adding it verbatim, then layering an
     animation on top so it draws in left → right when the section enters view. */
  .homepage .homepage__firm .homepage__firm--slider::before {
    content: "";
    position: absolute;
    display: block;
    width: 158px;
    height: 1px;
    left: -158px;
    top: 23px;
    background-color: #000;
    /* Higher than the curtains so the line still reads while the slider sits
       under the curtain layers. */
    z-index: 4;
    /* Animation default: line is collapsed to width 0, anchored at its left
       end, ready to grow rightward toward the slider when the section reveals. */
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 900ms cubic-bezier(0.22, 1, 0.36, 1);
    transition-delay: 100ms;
    will-change: transform;
  }
  .homepage .homepage__firm .homepage__firm--slider.is-revealed::before {
    transform: scaleX(1);
  }
  @media screen and (max-width: 991px) {
    /* Match the live theme: no connector below 991px. */
    .homepage .homepage__firm .homepage__firm--slider::before { content: none; }
  }
  @media (prefers-reduced-motion: reduce) {
    .homepage .homepage__firm .homepage__firm--slider::before {
      transform: scaleX(1) !important;
      transition: none !important;
    }
  }

  /* ===== Our Firm content — title, paragraph, button slide up one-by-one ===== */
  /* All three elements travel the same 20px, with identical duration + easing —
     only the start delay is staggered, so the motion reads as a single rhythm. */
  html.js .homepage__firm--content[data-anim="firm-text"] > h2,
  html.js .homepage__firm--content[data-anim="firm-text"] > p,
  html.js .homepage__firm--content[data-anim="firm-text"] > a {
    opacity: 0;
    transform: translate3d(0, 40px, 0);
    transition:
      opacity 700ms cubic-bezier(0.22, 1, 0.36, 1),
      transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
    will-change: opacity, transform;
  }
  /* The button is an <a class="btn-black">. The live theme doesn't set a
     `display` on it, so it stays `display: inline` — and per CSS spec,
     `transform` doesn't apply to non-atomic inline boxes. Result: opacity
     interpolates (which works on inline), but the 80px slide is silently
     dropped. Promoting it to `inline-block` makes it transformable.
     The theme also ships `transition: all ease 0.7s` on .btn-black at higher
     specificity — we re-declare ours with !important to win. */
  html.js .homepage__firm--content[data-anim="firm-text"] > a {
    display: inline-block !important;
    transform: translate3d(0, 40px, 0) !important;
    transition:
      opacity 700ms cubic-bezier(0.22, 1, 0.36, 1),
      transform 700ms cubic-bezier(0.22, 1, 0.36, 1) !important;
  }
  html.js .homepage__firm--content[data-anim="firm-text"].is-revealed > h2 { transition-delay: 0ms;   opacity: 1; transform: translate3d(0, 0, 0); }
  html.js .homepage__firm--content[data-anim="firm-text"].is-revealed > p  { transition-delay: 180ms; opacity: 1; transform: translate3d(0, 0, 0); }
  html.js .homepage__firm--content[data-anim="firm-text"].is-revealed > a  {
    transition-delay: 360ms !important;
    opacity: 1;
    transform: translate3d(0, 0, 0) !important;
  }

  @media (prefers-reduced-motion: reduce) {
    .homepage__firm--content[data-anim="firm-text"] > h2,
    .homepage__firm--content[data-anim="firm-text"] > p,
    .homepage__firm--content[data-anim="firm-text"] > a {
      opacity: 1 !important;
      transform: none !important;
      transition: none !important;
    }
  }

  /* ============================================================
     Practice Areas section
     ============================================================ */

  /* Side-tab font size — match the live theme spec (was rendering too large
     because some override on this page bumped the size). Forcing it via
     three layered selectors of escalating specificity so we win regardless
     of which other rule was previously bumping the size:
       1. simple chained-class match (same shape as the live theme rule)
       2. add the attribute selector our JS sets (extra class+attr specificity)
       3. add the explicit [data-toggle="tab"] attribute on each anchor
     Plus the inline-style fallback below in JS. */
  /* Visual match to the live site: the live theme's CSS declares weight 600 +
     letter-spacing 1px, but Google Fonts is only loading the weight-400 cut,
     so weight 600 falls back to a synthetic bold that's heavier and wider
     than what live actually renders. Use weight 400 + letter-spacing 0 here
     to reproduce the live appearance exactly. */
  .homepage .homepage__pa .homepage__pa--content ul li a,
  .homepage .homepage__pa .homepage__pa--content[data-anim="pa-text"] ul li a,
  html.js .homepage__pa--content[data-anim="pa-text"] ul li a[data-toggle="tab"] {
    font-size: 16px !important;
    letter-spacing: 0 !important;
    line-height: 23px !important;
    font-weight: 400 !important;
    font-family: "Source Sans Pro", Arial, sans-serif !important;
    color: rgba(0, 0, 0, 0.54);
  }
  .homepage .homepage__pa .homepage__pa--content ul li.active a,
  .homepage .homepage__pa .homepage__pa--content ul li:hover a {
    color: #000;
  }

  /* Text column — h2 slides up, then each tab li one-by-one. */
  html.js .homepage__pa--content[data-anim="pa-text"] h2,
  html.js .homepage__pa--content[data-anim="pa-text"] ul li {
    opacity: 0;
    transform: translate3d(0, 40px, 0);
    transition:
      opacity 700ms cubic-bezier(0.22, 1, 0.36, 1),
      transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
    will-change: opacity, transform;
  }
  html.js .homepage__pa--content[data-anim="pa-text"].is-revealed h2 { transition-delay:   0ms; opacity: 1; transform: translate3d(0, 0, 0); }
  html.js .homepage__pa--content[data-anim="pa-text"].is-revealed ul li:nth-child(1) { transition-delay: 180ms; opacity: 1; transform: translate3d(0, 0, 0); }

  /* The live theme offsets the active tab 15px to the right
     (`transform: translateX(15px)`). Our animation's end state is
     translate3d(0,0,0), and the .active rule's translateX(15px) would
     otherwise win as the END state — causing the first tab to interpolate
     between translate3d(0, 40px, 0) and translateX(15px), i.e. slide
     diagonally up-and-right instead of purely up.
     Bake the 15px X offset into BOTH the initial and revealed transforms
     so only Y changes during the animation. Higher specificity than the
     theme rule (added .data-anim attribute) so it wins. */
  html.js .homepage__pa--content[data-anim="pa-text"] ul li.active {
    transform: translate3d(15px, 40px, 0);
  }
  html.js .homepage__pa--content[data-anim="pa-text"].is-revealed ul li.active {
    transform: translate3d(15px, 0, 0);
  }
  html.js .homepage__pa--content[data-anim="pa-text"].is-revealed ul li:nth-child(2) { transition-delay: 250ms; opacity: 1; transform: translate3d(0, 0, 0); }
  html.js .homepage__pa--content[data-anim="pa-text"].is-revealed ul li:nth-child(3) { transition-delay: 320ms; opacity: 1; transform: translate3d(0, 0, 0); }
  html.js .homepage__pa--content[data-anim="pa-text"].is-revealed ul li:nth-child(4) { transition-delay: 390ms; opacity: 1; transform: translate3d(0, 0, 0); }
  html.js .homepage__pa--content[data-anim="pa-text"].is-revealed ul li:nth-child(5) { transition-delay: 460ms; opacity: 1; transform: translate3d(0, 0, 0); }
  html.js .homepage__pa--content[data-anim="pa-text"].is-revealed ul li:nth-child(6) { transition-delay: 530ms; opacity: 1; transform: translate3d(0, 0, 0); }
  html.js .homepage__pa--content[data-anim="pa-text"].is-revealed ul li:nth-child(7) { transition-delay: 600ms; opacity: 1; transform: translate3d(0, 0, 0); }
  html.js .homepage__pa--content[data-anim="pa-text"].is-revealed ul li:nth-child(8) { transition-delay: 670ms; opacity: 1; transform: translate3d(0, 0, 0); }

  /* Slider — same gold/black curtain reveal + image zoom-out as Our Firm. */
  html.js .homepage__pa--slider[data-anim="pa"] { position: relative; }
  html.js .homepage__pa--slider[data-anim="pa"] > .firm-curtain-wrap {
    position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 3;
  }
  html.js .homepage__pa--slider[data-anim="pa"] .firm-curtain {
    position: absolute; inset: 0; pointer-events: none; transform: translateY(0%);
    transition: transform 0.55s cubic-bezier(.42, 0, .58, 1);
    will-change: transform;
  }
  html.js .homepage__pa--slider[data-anim="pa"] .firm-curtain--gold  { z-index: 2; background: #b38100; transition-delay: 0.2s; }
  html.js .homepage__pa--slider[data-anim="pa"] .firm-curtain--black { z-index: 1; background: #000;    transition-delay: 0.6s; }
  html.js .homepage__pa--slider[data-anim="pa"].is-revealed .firm-curtain--gold  { transform: translateY(-110%); }
  html.js .homepage__pa--slider[data-anim="pa"].is-revealed .firm-curtain--black { transform: translateY(100%);  }

  html.js .homepage__pa--slider[data-anim="pa"] .homepage__pa--item__image {
    transform: scale(1.2);
    transition: transform 0.85s cubic-bezier(.42, 0, .58, 1);
    transition-delay: 0.6s;
    will-change: transform;
  }
  html.js .homepage__pa--slider[data-anim="pa"].is-revealed .homepage__pa--item__image {
    transform: scale(1);
  }

  /* Connector line — 118px (matches live spec). */
  .homepage .homepage__pa .homepage__pa--slider::before {
    content: ""; position: absolute; display: block;
    width: 118px; height: 1px; left: -118px; top: 23px;
    background-color: #000; z-index: 4;
    transform: scaleX(0); transform-origin: left center;
    transition: transform 900ms cubic-bezier(0.22, 1, 0.36, 1);
    transition-delay: 100ms;
    will-change: transform;
  }
  .homepage .homepage__pa .homepage__pa--slider.is-revealed::before {
    transform: scaleX(1);
  }
  @media screen and (max-width: 991px) {
    .homepage .homepage__pa .homepage__pa--slider::before { content: none; }
  }
  @media (prefers-reduced-motion: reduce) {
    .homepage__pa--content[data-anim="pa-text"] h2,
    .homepage__pa--content[data-anim="pa-text"] ul li,
    .homepage__pa--slider[data-anim="pa"] .homepage__pa--item__image {
      opacity: 1 !important; transform: none !important; transition: none !important;
    }
    .homepage__pa--slider[data-anim="pa"] > .firm-curtain-wrap { display: none !important; }
    .homepage .homepage__pa .homepage__pa--slider::before { transform: scaleX(1) !important; transition: none !important; }
  }

  /* ============================================================
     Highlights section
     ============================================================ */

  /* Allow the bg-image to be transformed: hand it off to a dedicated layer
     injected by JS (.highlights__bg) and clip overflow on the section so the
     scale doesn't bleed past its edges. */
  html.js .highlights[data-anim="highlights"] { overflow: hidden; }
  html.js .highlights[data-anim="highlights"] > .highlights__bg {
    position: absolute; inset: 0; z-index: 0;
    background-size: cover; background-position: center;
    transform: scale(1.18);
    transition: transform 1400ms cubic-bezier(.42, 0, .58, 1);
    will-change: transform;
  }
  html.js .highlights[data-anim="highlights"].is-revealed > .highlights__bg { transform: scale(1); }

  /* "Highlights" heading slides up */
  html.js .highlights[data-anim="highlights"] .ttl-col h3 {
    opacity: 0;
    transform: translate3d(0, 40px, 0);
    transition:
      opacity 700ms cubic-bezier(0.22, 1, 0.36, 1),
      transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
    will-change: opacity, transform;
  }
  html.js .highlights[data-anim="highlights"].is-revealed .ttl-col h3 {
    opacity: 1; transform: translate3d(0, 0, 0);
  }

  /* Left line grows from 0 → 100px (left to right) — lives on .ttl-col h3::after */
  html.js .highlights[data-anim="highlights"] .ttl-col h3::after {
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 900ms cubic-bezier(0.22, 1, 0.36, 1);
    transition-delay: 350ms;
    will-change: transform;
  }
  html.js .highlights[data-anim="highlights"].is-revealed .ttl-col h3::after {
    transform: scaleX(1);
  }

  /* Three highlight stripes fade up one-by-one */
  html.js .highlights[data-anim="highlights"] .high-item {
    opacity: 0;
    transform: translate3d(0, 24px, 0);
    transition:
      opacity 650ms cubic-bezier(0.22, 1, 0.36, 1),
      transform 650ms cubic-bezier(0.22, 1, 0.36, 1);
    will-change: opacity, transform;
  }
  html.js .highlights[data-anim="highlights"].is-revealed .high-item:nth-child(1) { transition-delay: 300ms; opacity: 1; transform: translate3d(0, 0, 0); }
  html.js .highlights[data-anim="highlights"].is-revealed .high-item:nth-child(2) { transition-delay: 480ms; opacity: 1; transform: translate3d(0, 0, 0); }
  html.js .highlights[data-anim="highlights"].is-revealed .high-item:nth-child(3) { transition-delay: 660ms; opacity: 1; transform: translate3d(0, 0, 0); }

  @media (prefers-reduced-motion: reduce) {
    .highlights[data-anim="highlights"] > .highlights__bg,
    .highlights[data-anim="highlights"] .ttl-col h3,
    .highlights[data-anim="highlights"] .ttl-col h3::after,
    .highlights[data-anim="highlights"] .high-item {
      opacity: 1 !important; transform: none !important; transition: none !important;
    }
  }

  /* ============================================================
     Recent News section
     ============================================================ */

  html.js .homepage__news--content[data-anim="news-text"] h2,
  html.js .homepage__news--content[data-anim="news-text"] a.btn-black {
    opacity: 0;
    transform: translate3d(0, 40px, 0);
    transition:
      opacity 700ms cubic-bezier(0.22, 1, 0.36, 1),
      transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
    will-change: opacity, transform;
  }
  html.js .homepage__news--content[data-anim="news-text"] a.btn-black {
    display: inline-block !important;
    transform: translate3d(0, 40px, 0) !important;
    transition:
      opacity 700ms cubic-bezier(0.22, 1, 0.36, 1),
      transform 700ms cubic-bezier(0.22, 1, 0.36, 1) !important;
  }
  html.js .homepage__news--content[data-anim="news-text"].is-revealed h2 {
    transition-delay: 0ms; opacity: 1; transform: translate3d(0, 0, 0);
  }
  html.js .homepage__news--content[data-anim="news-text"].is-revealed a.btn-black {
    transition-delay: 180ms !important; opacity: 1; transform: translate3d(0, 0, 0) !important;
  }

  /* News cards fade up one-by-one */
  html.js .homepage__news--posts[data-anim="news-posts"] > div {
    opacity: 0;
    transform: translate3d(0, 40px, 0);
    transition:
      opacity 700ms cubic-bezier(0.22, 1, 0.36, 1),
      transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
    will-change: opacity, transform;
  }
  html.js .homepage__news--posts[data-anim="news-posts"].is-revealed > div:nth-child(1) { transition-delay: 100ms; opacity: 1; transform: translate3d(0, 0, 0); }
  html.js .homepage__news--posts[data-anim="news-posts"].is-revealed > div:nth-child(2) { transition-delay: 280ms; opacity: 1; transform: translate3d(0, 0, 0); }
  html.js .homepage__news--posts[data-anim="news-posts"].is-revealed > div:nth-child(3) { transition-delay: 460ms; opacity: 1; transform: translate3d(0, 0, 0); }

  /* News connector line — matches live spec: 135px × 1px, left:-130px, top:23px.
     The live theme uses min-width: 135px (which wins over max-width: 102px),
     so the effective rendered width is 135px. Anchored via .homepage__news--posts. */
  .homepage .homepage__news .homepage__news--posts {
    position: relative; /* in case the live theme hasn't set this — needed for ::before anchor */
  }
  .homepage .homepage__news .homepage__news--posts::before {
    content: ""; position: absolute; display: block;
    width: 135px; height: 1px; left: -130px; top: 23px;
    background-color: #000; z-index: 1;
    transform: scaleX(0); transform-origin: left center;
    transition: transform 900ms cubic-bezier(0.22, 1, 0.36, 1);
    transition-delay: 100ms;
    will-change: transform;
  }
  .homepage .homepage__news .homepage__news--posts[data-anim="news-posts"].is-revealed::before {
    transform: scaleX(1);
  }
  @media screen and (max-width: 991px) {
    .homepage .homepage__news .homepage__news--posts::before { content: none; }
  }
  @media (prefers-reduced-motion: reduce) {
    .homepage .homepage__news .homepage__news--posts::before { transform: scaleX(1) !important; transition: none !important; }
  }

  @media (prefers-reduced-motion: reduce) {
    .homepage__news--content[data-anim="news-text"] h2,
    .homepage__news--content[data-anim="news-text"] a.btn-black,
    .homepage__news--posts[data-anim="news-posts"] > div {
      opacity: 1 !important; transform: none !important; transition: none !important;
    }
  }

  /* ============================================================
     Footer — videinfra.com-style parallax (footer is the TOP layer)
     ============================================================
     The footer sits at the natural document bottom in normal flow with a
     HIGH z-index (above the content). JS translates it on scroll: while the
     last viewport-height of scroll is still pending, the footer starts
     translated DOWN by an offset (.footer-parallax-offset px), and that
     offset decays to 0 as the user scrolls toward the document end.
     Effect: footer visually rises into view *faster* than the page scroll —
     a "catching up" parallax, identical to the Insights footer reveal on
     videinfra.com.
     The body has no whitespace below the footer because the footer is in
     normal flow (no extra spacer reserved). */
  html, body { margin: 0; padding: 0; }
  html.js body { padding-bottom: 0 !important; margin-bottom: 0 !important; overflow-x: clip; }

  /* Footer — sits at the natural document end in normal flow, no parallax,
     no transform. Bottom of document = bottom of footer (no empty space). */
  html.js .site-footer {
    position: relative;
    z-index: 1;
    margin-bottom: 0 !important;
  }

  /* Disable iOS/trackpad overscroll bounce so the dark footer can never reveal
     anything underneath it (no light strip, no html bleed). */
  html, body { overscroll-behavior-y: none; }

  /* Shorten the Recent News section's bottom padding to 20px (live theme is 90px
     top + 90px bottom; this trims the bottom while leaving the top untouched). */
  .homepage .homepage__news,
  .homepage__news {
    padding-bottom: 180px !important;
    margin-bottom: 0 !important;
  }
