/* Bluamoeba mobile experience
   Content-led phone layouts layered over the established desktop art direction. */

:root {
  --mobile-gutter: clamp(1.25rem, 5.6vw, 1.5rem);
  --mobile-section-space: clamp(4.5rem, 12vw, 6rem);
  --mobile-copy: clamp(1rem, 4.2vw, 1.125rem);
  --mobile-display: clamp(2.1rem, 9.5vw, 3rem);
  --mobile-section-headline: 1.5rem;
  --mobile-ease: cubic-bezier(.22, 1, .36, 1);
}

@media (max-width: 767px),
  (min-width: 768px) and (max-width: 1023px) and (orientation: portrait) {
  html {
    scroll-padding-top: calc(var(--persistent-nav-offset, 6.25rem) + env(safe-area-inset-top));
    /* A sideways swipe that reaches the end of a card rail used to chain into
       the document and drag the whole page left, leaving the copy pinned to
       the edge (or off it) until you swiped back. Nothing on a phone should
       pan horizontally: the decks own that axis. */
    overscroll-behavior-x: none;
  }

  body {
    min-width: 20rem;
    /* `clip`, not `hidden`: hidden would make the body a scroll container and
       break every sticky/fixed thing inside it. This propagates to the
       viewport and gives the page nowhere to pan to. */
    overflow-x: clip;
    overscroll-behavior-x: none;
  }

  /* Every horizontal rail keeps its own gesture. Without this the last card
     hands the swipe to the page. */
  #pf-bento-stack,
  .xsvc-mobile__deck,
  #testimonials .ct-grid,
  .home-journal__grid,
  .np-grid,
  .cli-grid-scroll,
  .cli-logo-row,
  .proj-filters,
  .kp-filters {
    overscroll-behavior-x: contain;
  }

  header#header .nav,
  header.topbar .nav {
    position: relative;
    isolation: isolate;
    min-height: calc(4.75rem + env(safe-area-inset-top));
    padding:
      max(.75rem, env(safe-area-inset-top))
      max(var(--mobile-gutter), env(safe-area-inset-right))
      .75rem
      max(var(--mobile-gutter), env(safe-area-inset-left));
  }

  header#header .nav::before,
  header.topbar .nav::before {
    content: "";
    position: absolute;
    inset:
      max(.35rem, env(safe-area-inset-top))
      max(.75rem, env(safe-area-inset-right))
      .35rem
      max(.75rem, env(safe-area-inset-left));
    z-index: 0;
    background: color-mix(in srgb, var(--nav-menu-bg, #c8c9cc) var(--nav-menu-opacity, 78%), transparent);
    -webkit-backdrop-filter: blur(14px) saturate(112%);
    backdrop-filter: blur(14px) saturate(112%);
    pointer-events: none;
  }

  header#header .nav > *,
  header.topbar .nav > * {
    position: relative;
    z-index: 1;
  }

  header#header .brand,
  header.topbar .brand {
    min-height: 2.75rem;
    display: inline-flex;
    align-items: center;
    transform: none;
  }

  header#header .brand-mark,
  header.topbar .brand-mark {
    height: 2rem;
  }

  .burger {
    width: 2.75rem;
    height: 2.75rem;
    min-width: 2.75rem;
    min-height: 2.75rem;
    margin-right: -.625rem;
    font-size: 1.5rem;
    touch-action: manipulation;
  }

  .js-carousel__button--prev,
  .js-carousel__button--next {
    min-width: 2.75rem;
    min-height: 2.75rem;
  }

  .menu {
    top: calc(100% + .5rem);
    right: 0;
    width: min(18rem, calc(100vw - (2 * var(--mobile-gutter))));
  }

  .menu-links {
    border-radius: .75rem;
    padding: .5rem;
  }

  .menu.open .menu-links,
  .menu.is-open .menu-links {
    max-width: min(18rem, calc(100vw - (2 * var(--mobile-gutter))));
  }

  .menu a.m-link,
  .menu .nav-cta {
    min-width: 2.75rem;
    min-height: 2.75rem;
    padding: .75rem .875rem;
    align-items: center;
  }

  a:focus-visible,
  button:focus-visible,
  [role="button"]:focus-visible {
    outline: 2px solid currentColor !important;
    outline-offset: 3px;
  }

  #site-footer .foot-grid a,
  #site-footer .foot-legal nav a {
    min-height: 2.75rem;
    display: flex;
    align-items: center;
  }

  #site-footer .foot-idea h2 {
    max-width: 15ch;
    font-size: clamp(1.75rem, 8vw, 2.25rem);
    line-height: 1.04;
    letter-spacing: -.035em;
    text-wrap: balance;
  }

  #site-footer .foot-idea h2 .headline-keep {
    white-space: normal;
  }

  #site-footer .foot-grid a,
  #site-footer .foot-grid p,
  #site-footer .foot-offices-body {
    font-size: .9375rem;
    line-height: 1.55;
  }

  /* Homepage: one composed mobile narrative, not desktop pinning.

     NOTE — the hero block below is now mostly superseded. home-hero-x.css owns
     the hero at every breakpoint and writes its rules as
     `html body #top.hero-x …` (specificity 122) precisely so it beats both the
     runtime #cmsFieldStyles and the `body.home-page #top …` (121) selectors
     here. What is left standing in this block are the properties hero-x does
     not set. Change hero type or hero layout in home-hero-x.css, not here. */
  body.home-page #top {
    height: auto;
    min-height: 0;
    overflow: hidden;
    scroll-margin-top: 0;
  }

  body.home-page #top .hero-row {
    padding:
      calc(5.75rem + env(safe-area-inset-top))
      var(--mobile-gutter)
      1rem;
    gap: 0;
  }

  body.home-page #top .hero-title,
  body.home-page #top .hero-title [style*="font-size"] {
    max-width: 9.5ch;
    font-size: var(--mobile-display) !important;
    line-height: .96 !important;
    letter-spacing: -.04em !important;
    text-wrap: balance;
  }

  body.home-page #top .hero-title .ln {
    padding-bottom: .12em;
    margin-bottom: -.06em;
  }

  body.home-page #top .hero-subtext-mask {
    margin-top: clamp(1.5rem, 6vw, 2rem);
  }

  body.home-page #top .hero-subtext,
  body.home-page #top .hero-subtext [style*="font-size"] {
    max-width: 31ch;
    font-size: var(--mobile-copy) !important;
    line-height: 1.42 !important;
    letter-spacing: -.012em;
    text-wrap: pretty;
  }

  body.home-page .intro-bridge {
    height: auto;
    overflow: hidden;
  }

  /* Paired with the organism-journey phone guard: nothing paints here, so the
     canvas is only a stacking-context tax. */
  body.no-organism-art #organism-gl,
  body.no-organism-art .organism-gl-fallback,
  body.no-organism-art #organism-cursor {
    display: none !important;
  }

  body.home-page .oj-scene--manifesto,
  body.home-page .oj-scene--numbers {
    height: auto !important;
  }

  body.home-page .oj-pin,
  body.home-page .oj-manifesto-pin,
  body.home-page .oj-number-pin {
    position: relative !important;
    inset: auto !important;
    height: auto !important;
    min-height: 0 !important;
    overflow: visible;
  }

  /* Consecutive full-rhythm stages doubled their padding into ~150px voids.
     One shared rhythm keeps the journey reading as a continuous scroll. */
  body.home-page .oj-intro-stage {
    position: relative;
    inset: auto;
    min-height: 0;
    justify-content: flex-start;
    gap: 1.75rem;
    padding: calc(var(--mobile-section-space) * .62) var(--mobile-gutter);
  }

  body.home-page .oj-intro-title {
    order: 0;
    position: relative !important;
    inset: auto !important;
    width: 100%;
    opacity: 1 !important;
    visibility: visible !important;
    translate: none !important;
  }

  body.home-page .oj-manifesto-in {
    order: 1;
    position: relative !important;
    inset: auto !important;
    width: 100%;
    max-width: none;
    margin: 0;
    padding: 0;
    text-align: left;
    overflow: visible;
    opacity: 1 !important;
    visibility: visible !important;
    transform: none !important;
  }

  html body.home-page #intro-bridge .oj-manifesto-in {
    width: 100% !important;
    max-width: none !important;
    height: auto !important;
    min-height: 0 !important;
    max-height: none !important;
    overflow: visible !important;
  }

  body.home-page .intro-bridge-title-wrap {
    align-items: flex-start;
    flex-direction: column;
    gap: .35rem;
    white-space: normal;
  }

  body.home-page .intro-bridge-exit-left,
  body.home-page .intro-bridge-exit-right {
    translate: none !important;
    transform: none !important;
    opacity: 1 !important;
  }

  body.home-page #intro-bridge-word-connect {
    opacity: 1 !important;
  }

  body.home-page .intro-bridge-word,
  body.home-page #intro-bridge-word-stories,
  body.home-page #intro-bridge-word-connect {
    --oj-title-size: var(--mobile-section-headline);
    font-size: var(--oj-title-size) !important;
    line-height: .9 !important;
    letter-spacing: -.04em;
  }

  body.home-page .oj-manifesto-copy,
  body.home-page .oj-manifesto-copy [style*="font-size"] {
    display: block !important;
    width: 100% !important;
    max-width: 34ch;
    height: auto !important;
    max-height: none !important;
    overflow: visible !important;
    color: var(--oj-fg);
    font-size: 1rem !important;
    line-height: 1.62 !important;
    letter-spacing: -.008em;
    text-wrap: pretty;
  }

  body.home-page .oj-manifesto-copy .oj-mw {
    display: inline !important;
    filter: none !important;
  }

  html body.home-page #intro-bridge #organism-manifesto.oj-manifesto-copy,
  html body.home-page #intro-bridge #organism-manifesto.oj-manifesto-copy .oj-mw {
    font-size: 1rem !important;
    line-height: 1.62 !important;
    letter-spacing: -.008em !important;
  }

  html body.home-page #intro-bridge #organism-manifesto.oj-manifesto-copy {
    width: 100% !important;
    max-width: none !important;
  }

  body.home-page .au-seq-stage {
    gap: 1.5rem;
    padding: calc(var(--mobile-section-space) * .62) var(--mobile-gutter);
  }

  /* Headline + icon loop share one row; icon height tracks the 2-line title.
     Keep the mark as an accent — never a full-column illustration. */
  body.home-page .au-seq-copy {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 1rem;
    width: 100%;
    max-width: 100%;
  }

  body.home-page .au-seq-head {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: .75rem;
    width: 100%;
    font-size: var(--mobile-section-headline);
  }

  body.home-page .au-seq-title,
  body.home-page .au-seq-title [style*="font-size"] {
    width: auto;
    max-width: none;
    flex: 1 1 auto;
    min-width: 0;
    padding: 0;
    font-size: 1em;
    line-height: .96;
    letter-spacing: -.04em;
  }

  body.home-page .au-seq-art {
    flex: 0 0 auto;
    width: 2em;
    height: 2em;
    max-width: none;
    margin-inline: 0;
    align-self: center;
  }

  body.home-page .au-seq-icon,
  body.home-page .au-seq-art-img {
    width: 100%;
    height: 100%;
    object-fit: contain;
  }

  body.home-page .au-seq-sub,
  body.home-page .au-seq-sub [style*="font-size"] {
    max-width: 36ch;
    /* Size/line-height defaults — do not !important over CMS field styles. */
    font-size: var(--mobile-copy);
    line-height: 1.5;
    letter-spacing: -.01em;
    text-wrap: pretty;
  }

  body.home-page .oj-number-pin {
    gap: 1.25rem;
    padding:
      calc(var(--mobile-section-space) * .62) var(--mobile-gutter)
      calc(var(--mobile-section-space) * .35);
  }

  body.home-page .oj-number-head {
    padding-inline: 0;
    opacity: 1 !important;
  }

  body.home-page .oj-number-head h2,
  body.home-page .oj-number-head h2 [style*="font-size"] {
    max-width: 12ch;
    font-size: var(--mobile-section-headline) !important;
    line-height: 1 !important;
    letter-spacing: -.04em !important;
  }

  html body.home-page #organism-numbers .oj-number-head h2.mobile-three-line-heading {
    width: 100%;
    max-width: none;
    font-size: clamp(1.125rem, 5.97vw, var(--mobile-section-headline)) !important;
    line-height: 1.05 !important;
    text-wrap: initial;
  }

  /* Two columns: eight stats down a single column made the section a scroll
     chore, and half-width leaves the numerals plenty of room. The rules run
     across both cells, so each row still reads as one line of the table. */
  body.home-page .oj-number-wall {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: none;
    grid-auto-columns: auto;
    grid-auto-flow: row;
    column-gap: clamp(1rem, 4.5vw, 1.5rem);
    row-gap: 0;
    margin: 0;
    padding: 0;
    overflow: visible;
    border-top: 1px solid rgba(16, 16, 16, .2);
    background: transparent;
  }

  body.home-page .oj-number-wall::-webkit-scrollbar {
    display: none;
  }

  /* The translucent white cell reads as a slab once the cards are half-width
     and butt against each other — the rules alone carry the table, and match
     the ruled editorial treatment used elsewhere on the phone layout. */
  body.home-page .oj-number-card {
    --v: 1 !important;
    min-height: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: .375rem;
    padding: .875rem 0 1rem;
    border: 0;
    border-bottom: 1px solid rgba(16, 16, 16, .2);
    background: transparent !important;
    opacity: 1 !important;
    filter: none !important;
    scroll-snap-align: start;
  }

  body.home-page .oj-number-value {
    font-size: clamp(2rem, 9vw, 2.5rem);
    line-height: .92;
    /* Counting digits change width every frame — tabular figures stop the
       label below from twitching left and right through the count-up. */
    font-variant-numeric: tabular-nums;
  }

  body.home-page .oj-number-label {
    display: block;
    height: auto;
    min-height: 0;
    max-width: none;
    overflow: visible;
    font-size: .6875rem;
    line-height: 1.4;
    -webkit-line-clamp: unset;
    line-clamp: unset;
  }

  body.home-page .oj-number-card:first-of-type .oj-number-label {
    font-size: .625rem;
    text-wrap: balance;
  }

  /* ── Selected work ───────────────────────────────────────────────────────
     Phones get a native scroll-snap deck instead of the desktop pinned rail:
     the OS owns the momentum, one swipe = one project, and the section costs
     one viewport of scroll instead of three. */

  body.home-page #work {
    padding: max(var(--mobile-section-space), var(--persistent-nav-offset, 6.25rem)) 0 calc(var(--mobile-section-space) * .55);
    scroll-margin-top: var(--persistent-nav-offset, 6.25rem);
  }

  body.home-page #work .work-shell {
    padding-inline: 0;
  }

  body.home-page #portfolio-frame {
    display: flex;
    flex-direction: column;
    gap: 1.75rem;
  }

  /* The head is a two-column desktop grid (copy | archive mosaic). Hiding the
     mosaic alone left its column in place, so the copy stayed at half width. */
  body.home-page .work-head {
    display: block;
    gap: .75rem;
    margin: 0;
    padding-inline: var(--mobile-gutter);
  }

  /* The archive mosaic is a desktop-scale collage; at 45vw it reads as broken
     thumbnails, so the phone layout drops it and keeps the headline full-width. */
  body.home-page .work-head__funnel,
  body.home-page .work-rail-progress {
    display: none !important;
  }

  body.home-page .work-head__title,
  body.home-page .work-head__title [style*="font-size"] {
    max-width: none !important;
    font-size: var(--mobile-section-headline) !important;
    line-height: .98 !important;
    letter-spacing: -.035em !important;
  }

  body.home-page .work-head__copy {
    gap: .875rem;
  }

  body.home-page .work-head__copy p {
    max-width: 32ch;
    font-size: var(--mobile-copy);
    line-height: 1.45;
    letter-spacing: -.01em;
  }

  body.home-page .pf-bento-stack {
    display: block;
    width: 100%;
    min-width: 0;
    padding: 0;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scroll-padding-inline-start: var(--mobile-gutter);
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

  body.home-page .pf-bento-stack::-webkit-scrollbar {
    display: none;
  }

  body.home-page .pf-bento-list {
    width: max-content;
    display: flex;
    flex-direction: row;
    align-items: stretch;
    gap: .875rem;
    padding-inline: var(--mobile-gutter);
    transform: none !important;
  }

  body.home-page .work-card {
    width: min(20.5rem, 82vw);
    flex: none;
    scroll-snap-align: start;
    scroll-snap-stop: always;
    opacity: 1 !important;
    visibility: visible !important;
    transform: none !important;
  }

  body.home-page .work-card > a,
  body.home-page .work-card__frame {
    height: 100%;
  }

  body.home-page .work-card__frame {
    display: flex;
    flex-direction: column;
  }

  /* portfolio-bento.css stretches the media to height:100% for portrait
     tablets — that was for the old full-height card. In the deck it swallows
     the whole card and buries the copy. */
  body.home-page .work-card__media,
  body.home-page .work-card--flip .work-card__media {
    width: 100% !important;
    max-width: 100% !important;
    height: auto !important;
    flex: 0 0 auto;
    align-self: auto;
    aspect-ratio: 4 / 3;
    border-radius: var(--container-radius, .625rem);
    transform: none !important;
  }

  body.home-page .work-card__media img {
    width: 100% !important;
    max-width: 100% !important;
    height: 100% !important;
    object-fit: cover;
    transform: none !important;
  }

  body.home-page .work-card__content,
  body.home-page .work-card--flip .work-card__content {
    flex: 1 1 auto;
    height: auto !important;
    min-height: 0 !important;
    display: flex;
    flex-direction: column;
    padding-top: 1rem;
    overflow: visible;
  }

  body.home-page .work-card__heading {
    display: flex;
    flex-direction: column;
    gap: .5rem;
  }

  body.home-page .work-card__heading p {
    font-size: .6875rem;
    line-height: 1.4;
    letter-spacing: .12em;
  }

  body.home-page .work-card__heading h3 {
    max-width: none;
    font-size: 1.25rem;
    line-height: 1.12;
    letter-spacing: -.02em;
    white-space: normal;
    text-wrap: balance;
  }

  /* Summaries are CMS copy of unknown length — three lines, then an explicit
     control. Clamping alone used to slice a sentence mid-line with no way back. */
  body.home-page .work-card__summary {
    display: -webkit-box;
    margin: .75rem 0 .25rem;
    max-width: none;
    overflow: hidden;
    font-size: .875rem;
    line-height: 1.5;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    line-clamp: 3;
  }

  body.home-page .work-card.is-summary-open .work-card__summary {
    display: block;
    overflow: visible;
    -webkit-line-clamp: none;
    line-clamp: none;
  }

  /* Sits inside the card's own <a>, so mobile-motion.js stops the click from
     reaching it — styled as text, not a second competing button. */
  body.home-page .work-card__more {
    min-height: 2.75rem;
    display: inline-flex;
    align-items: center;
    margin-bottom: .5rem;
    font-size: .6875rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    text-decoration: underline;
    text-underline-offset: .35em;
    cursor: pointer;
  }

  /* portfolio-bento.css sets align-self:end on the meta list. In the desktop
     card that is a row-flex cross-axis (vertical). Here the card is a column
     flex, so the same declaration pushed narrow meta blocks to the RIGHT —
     SHEIN sat 51px in, Emerson 26px, breaking the left edge the headline sets. */
  body.home-page .work-card__meta {
    align-self: stretch;
    width: 100%;
    margin-top: auto;
  }

  /* One fixed row height across every card, so the CLIENT / SERVICES / LOCATION
     lines land at the same y as you swipe instead of jumping per project. */
  body.home-page .work-card__meta > div {
    grid-template-columns: 4.5rem minmax(0, 1fr);
    align-items: start;
    gap: .75rem;
    min-height: 3.125rem;
    padding: .5rem 0;
  }

  body.home-page .work-card__meta dt,
  body.home-page .work-card__meta dd {
    font-size: .6875rem;
    line-height: 1.45;
  }

  /* Two lines is the tallest a value gets; beyond that the row would set the
     height of every other row on every other card. */
  body.home-page .work-card__meta dd {
    display: -webkit-box;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
  }

  body.home-page .work-card__arrow {
    min-height: 2.75rem;
    display: flex;
    align-items: center;
    margin-top: .5rem;
    padding: .625rem 0;
    font-size: .6875rem;
  }

  /* Deck position readout — dots plus "02 / 06". Built by mobile-motion.js. */
  .work-deck-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-top: -.5rem;
    padding-inline: var(--mobile-gutter);
  }

  .work-deck-dots {
    display: flex;
    align-items: center;
    gap: .375rem;
  }

  .work-deck-dots i {
    width: .375rem;
    height: .375rem;
    border-radius: 50%;
    background: currentColor;
    opacity: .25;
    transition: opacity .22s var(--mobile-ease), transform .22s var(--mobile-ease);
  }

  .work-deck-dots i.is-active {
    opacity: 1;
    transform: scale(1.35);
  }

  .work-deck-count {
    font-size: .6875rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    font-variant-numeric: tabular-nums;
    opacity: .55;
  }

  /* The archive is the deck's closing slide, not a block underneath it — it
     swipes in as panel 07 and carries the desktop heart mosaic with it.
     portfolio-bento.js appends it into .pf-bento-list on phones. */
  /* Three bands that rhyme with a project card: art at the top where the photo
     sits, copy through the middle, CTA on the same bottom line as "View case
     study". .work-archive__copy is display:contents so its h3 and link can be
     placed into those bands individually. */
  body.home-page .work-archive {
    width: min(20.5rem, 82vw);
    flex: none;
    scroll-snap-align: start;
    scroll-snap-stop: always;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr) auto;
    align-items: start;
    justify-content: stretch;
    gap: 0;
    margin: 0;
    padding: 0;
    border-top: 0;
  }

  /* 75% of the panel is exactly the height of a 4:3 project photo, so a square
     heart lands with both its top AND bottom edges on the neighbouring card's
     image — and the remaining 25% is the air that separates it from the slide
     before it. */
  body.home-page .work-archive__mosaic {
    display: grid !important;
    grid-row: 1;
    grid-column: 1;
    width: 75%;
    max-width: 100%;
    aspect-ratio: 1;
    justify-self: start;
    align-self: start;
    gap: .1875rem;
  }

  /* The bloom is scrubbed by the desktop rail, which phones don't run — the
     cells are settled by portfolio-bento.js, so pin them visible here too. */
  body.home-page .work-archive__mosaic-cell {
    opacity: 1 !important;
    transform: none !important;
  }

  body.home-page .work-archive__copy {
    display: contents;
  }

  /* Sits on the same line as a project name: the heart matches the photo's
     height, so clearing it by the card's own content-padding + eyebrow puts
     this headline at the exact y the titles occupy on every other slide. */
  body.home-page .work-archive h3 {
    grid-row: 2;
    grid-column: 1;
    align-self: start;
    justify-self: start;
    /* Match the heart width and keep the archive headline directly beneath it. */
    width: 75%;
    margin: 1.5rem 0 0;
    max-width: 75%;
    font-size: clamp(1.5rem, 6.6vw, 1.6875rem) !important;
    line-height: 1.2 !important;
    letter-spacing: -.02em;
    text-align: center;
  }

  html body.home-page #work .work-archive h3 [data-cms="work.archive_title"],
  html body.home-page #work .work-archive h3 [data-cms="work.archive_emphasis"] {
    font-size: inherit !important;
    line-height: inherit !important;
    letter-spacing: inherit !important;
  }

  html body.home-page #work .work-archive h3 [data-cms="work.archive_title"] {
    display: inline-block;
    max-width: 8em;
  }

  body.home-page .work-archive__link {
    grid-row: 3;
    grid-column: 1;
    align-self: end;
    justify-self: start;
    justify-content: center;
    width: 75%;
    min-width: 0;
    min-height: 2.75rem;
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    /* Matches .work-card__arrow's padding so both CTAs share a baseline. */
    margin-top: .5rem;
    padding: .625rem 0;
    text-align: center;
  }

  /* ── Services ────────────────────────────────────────────────────────────
     The live section is the .xsvc- deck (services-experiment), not the older
     .svc- showcase. Phones drop the pinned panel entirely and read the deck
     left-to-right, so everything here is about making one card legible at a
     time rather than compressing the desktop composition. */

  /* Two stacked sections each paying full rhythm reads as a void. Where they
     meet, the pair splits one gap between them. */
  body.home-page #services.xsvc {
    padding: max(calc(var(--mobile-section-space) * .55), var(--persistent-nav-offset, 6.25rem)) 0 var(--mobile-section-space) !important;
    scroll-margin-top: var(--persistent-nav-offset, 6.25rem);
  }

  body.home-page #services .xsvc-intro__headline-stage {
    min-block-size: 2.5rem;
  }

  body.home-page #services .xsvc-intro {
    gap: 1.5rem;
    margin-block-end: 2rem;
    padding-inline: var(--mobile-gutter);
  }

  /* Right-aligned copy is a desktop counterweight to the kinetic line on the
     left. Stacked on a phone it just reads as a ragged left edge. */
  body.home-page #services .xsvc-intro__aside {
    align-items: flex-start;
    gap: .75rem;
    text-align: left;
  }

  body.home-page #services .xsvc-intro__title {
    max-width: 18ch;
    font-size: var(--mobile-section-headline) !important;
    line-height: 1.06;
    letter-spacing: -.03em;
    text-wrap: balance;
  }

  body.home-page #services .xsvc-intro__sub {
    max-width: 36ch;
    font-size: var(--mobile-copy) !important;
    line-height: 1.5;
    white-space: normal;
    text-wrap: pretty;
  }

  body.home-page #services .xsvc-intro__kinetic {
    font-size: clamp(1.35rem, 5.6vw, 1.75rem);
  }

  /* A CMS field style sizes the prefix at 35px against a 21.6px box. Inherit
     so the two halves of one sentence are one size. */
  body.home-page #services .xsvc-intro__we {
    font-size: inherit !important;
    line-height: inherit !important;
  }

  /* mobile-motion.js reparents this under the swipe hint — as a caption for
     the deck it is reading, not a headline competing with the section title.

     inline-size:auto is load-bearing: services-experiment.css sizes this stage
     100% for its own layout, and 100% plus a gutter margin on each side put
     the box 42px wider than the screen. It was the only unclipped horizontal
     overflow on the page, and the reason the homepage could be dragged
     sideways when the other pages could not. The margins do the insetting. */
  body.home-page #services .xsvc-mobile .xsvc-intro__headline-stage {
    min-block-size: 0;
    inline-size: auto;
    margin: 0 var(--mobile-gutter) 1rem;
  }

  body.home-page #services .xsvc-mobile__hint {
    display: none;
  }

  body.home-page #services .xsvc-mobile__deck {
    gap: .875rem;
    padding-inline: var(--mobile-gutter);
    scroll-padding-inline-start: var(--mobile-gutter);
    overscroll-behavior-x: contain;
  }

  /* Peek the next card instead of filling the viewport edge-to-edge — the
     cut-off neighbour is what tells a thumb there is more to the right. */
  body.home-page #services .xsvc-mobile-card {
    flex: 0 0 min(20.5rem, 82vw);
    min-block-size: 0;
    scroll-snap-align: start;
    border-radius: var(--container-radius, .625rem);
  }

  body.home-page #services .xsvc-mobile-card__art {
    block-size: 14rem;
    padding: .75rem;
  }

  body.home-page #services .xsvc-mobile-card__body {
    --xsvc-slide-pad: 1.25rem;
    gap: 0;
  }

  body.home-page #services .xsvc-mobile-card__title {
    max-inline-size: 14ch;
    font-size: 1.5rem;
    line-height: 1.04;
  }

  body.home-page #services .xsvc-mobile-card__desc {
    margin: .875rem 0 1.5rem;
    max-inline-size: 34ch;
    font-size: .9375rem;
    line-height: 1.5;
  }

  /* The decorative plus-grid starts at 40% of the card and ran straight through
     the description. The card art above already carries the same motif. */
  body.home-page #services .xsvc-mobile-card .xsvc-mini-grid {
    display: none !important;
  }

  body.home-page #services .xsvc-mobile-card .xsvc-scope__list {
    font-size: .8125rem;
    line-height: 1.45;
  }

  /* Replaced by the shared dots + counter readout (mobile-motion.js) so both
     decks on the page report position the same way. */
  body.home-page #services .xsvc-mobile__progress {
    display: none !important;
  }

  body.home-page #services .work-deck-nav {
    margin-top: 1rem;
  }

  body.home-page .clients {
    scroll-margin-top: var(--persistent-nav-offset, 6.25rem);
  }

  /* ── Clients + testimonials ───────────────────────────────────────────────
     The 2026-08 build replaced the logo tile grid with three marquee lanes
     (.cli-logo-row / .cli-logo-track) and made the first testimonial an
     image-backed "LED" card with a frosted quote panel floating over it.
     Both are desktop compositions. This sheet now loads last, so the phone
     layer can restate them without an !important war. */

  html body.home-page #clients .cli-layout,
  html body.home-page #clients .cli-layout.wrap {
    --client-grid-gap: .75rem;
    --clients-testimonial-gap: 2rem;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    grid-template-areas: "copy" "logos" "testimonials";
    row-gap: 1.75rem;
    /* The deck readout closes the section; a full rhythm under it stacked with
       the next section's own into a void. */
    padding:
      max(var(--mobile-section-space), var(--persistent-nav-offset, 6.25rem)) var(--mobile-gutter)
      calc(var(--mobile-section-space) * .55) !important;
  }

  html body.home-page #clients .cli-layout > * {
    width: 100%;
    max-width: 100%;
    min-width: 0;
  }

  /* Desktop hangs this copy off the right edge as a counterweight to the logo
     wall. In one column that reads as a stray indent — and at 22px the headline
     was ending flush against the gutter. The page's spine is the left margin. */
  html body.home-page #clients .cli-copy {
    justify-self: start;
    align-items: flex-start;
    width: 100%;
    text-align: left;
  }

  html body.home-page #clients .cli-copy h2,
  html body.home-page #clients .cli-copy h2[data-cms-html],
  html body.home-page #clients .cli-copy h2 [style*="font-size"] {
    max-width: none;
    font-family: "Aeonik", sans-serif !important;
    font-size: var(--mobile-section-headline) !important;
    font-weight: 600 !important;
    line-height: 1.15 !important;
    letter-spacing: -.025em !important;
    text-align: left;
    white-space: nowrap;
    text-wrap: nowrap;
  }

  html body.home-page #clients .cli-copy-sub {
    max-width: 40ch;
    text-align: left;
  }

  html body.home-page #clients .cli-copy-sub,
  html body.home-page #clients #testimonials .ct-headline-sub {
    max-width: 40ch !important;
    font-size: .8125rem !important;
    line-height: 1.5 !important;
    text-align: left;
  }

  /* Logo lanes: three rows, sized off the viewport so a lane always shows
     ~3.5 marks — enough to read as a wall, wide enough that each mark still
     has air. The track is animated by home-clients-motion.js. */
  html body.home-page #clients .cli-logos-panel {
    --cli-gap: .5rem;
    --cli-card-size: calc((100vw - (2 * var(--mobile-gutter)) - (2.5 * .5rem)) / 3.5);
    --cli-card-height: calc(var(--cli-card-size) * .56);
    --cli-row-gap: .3rem;
    margin-bottom: var(--clients-testimonial-gap);
  }

  html body.home-page #clients .cli-card-logo img,
  html body.home-page #clients .cli-card-logo svg {
    max-width: 88%;
    max-height: 64%;
  }

  html body.home-page #clients .cli-card-logo[data-cli-fit="mark"] img,
  html body.home-page #clients .cli-card-logo img[data-cli-fit="mark"] {
    max-width: 62%;
    max-height: 72%;
  }

  /* Testimonial heading sits at the same level as the clients headline. */
  html body.home-page #clients .ct-headline,
  html body.home-page #clients .ct-headline [style*="font-size"] {
    max-width: none !important;
    font-size: var(--mobile-section-headline) !important;
    line-height: 1.15 !important;
    letter-spacing: -.025em !important;
  }

  /* The badge was dropping to its own line under a two-line headline. At one
     line it belongs on the end of the sentence. */
  html body.home-page #clients .ct-headline {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    gap: .5rem;
    white-space: nowrap;
  }

  html body.home-page #clients .ct-headline > [data-cms-html] {
    flex: 0 1 auto;
    min-width: 0;
    font-size: inherit !important;
    line-height: inherit !important;
    letter-spacing: inherit !important;
  }

  html body.home-page #clients #testimonials .ct-layout {
    row-gap: .75rem;
  }

  html body.home-page #clients #testimonials .ct-top {
    margin-bottom: 0;
  }

  /* Arrows are redundant next to a snap rail you can thumb, and the desktop
     build parks them absolutely over the first card. */
  html body.home-page #clients .cli-layout > .ct-controls,
  html body.home-page #clients #testimonials .ct-controls {
    display: none !important;
  }

  html body.home-page #clients #testimonials .ct-viewport {
    overflow: visible;
  }

  /* One card per swipe with a slice of the next one showing. Card heights are
     content-led: --ct-card-height is the desktop equal-height measurement and
     would pad every short quote out to the tallest one. */
  html body.home-page #clients #testimonials .ct-grid {
    --ct-gap: .75rem;
    align-items: stretch;
    gap: var(--ct-gap);
    padding-block: .125rem;
    scroll-snap-type: x mandatory;
    scroll-padding-inline-start: 0;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }

  html body.home-page #clients #testimonials .ct-grid::-webkit-scrollbar {
    display: none;
  }

  html body.home-page #clients #testimonials .ct-card,
  html body.home-page #clients #testimonials .ct-card[data-quote-length="long"],
  html body.home-page #clients #testimonials .ct-card.ct-card--led {
    flex: 0 0 86%;
    max-width: 86%;
    height: auto !important;
    min-height: 0;
    align-self: stretch;
    scroll-snap-align: start;
    scroll-snap-stop: always;
    opacity: 1 !important;
  }

  /* Every card is the same object: a paper surface holding a quote and the
     person who said it. The LED card keeps its photograph, as a band at the
     top of that surface instead of a backdrop behind the words. */
  html body.home-page #clients #testimonials .ct-card-shell,
  html body.home-page #clients #testimonials .ct-card--led .ct-card-shell,
  html body.home-page #clients #testimonials .ct-card--led.is-active .ct-card-shell {
    display: flex;
    flex-direction: column;
    height: 100% !important;
    min-height: 15rem !important;
    max-height: none !important;
    aspect-ratio: auto;
    padding: 0 !important;
    border-radius: var(--container-radius, .75rem);
    background: var(--testimonials-container-color, #fff) !important;
    color: var(--testimonials-card-ink, #10121a);
    overflow: hidden;
  }

  html body.home-page #clients #testimonials .ct-card--led .ct-led-media {
    position: relative;
    inset: auto;
    flex: 0 0 auto;
    width: 100%;
    height: 8.5rem;
  }

  html body.home-page #clients #testimonials .ct-card--led .ct-led-image {
    filter: none;
  }

  /* The scrim and the soft-light dot screen exist to hold white type over the
     photo. Nothing sits on it here. */
  html body.home-page #clients #testimonials .ct-card--led .ct-led-scrim,
  html body.home-page #clients #testimonials .ct-card--led .ct-led-media::after {
    display: none;
  }

  html body.home-page #clients #testimonials .ct-card--led .ct-frost-card {
    position: static;
    flex: 1 1 auto;
    width: 100%;
    min-width: 0;
    min-height: 0;
    margin: 0;
    padding: 1.125rem;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }

  html body.home-page #clients #testimonials .ct-card:not(.ct-card--led) .ct-card-shell {
    padding: 1.125rem !important;
  }

  html body.home-page #clients #testimonials .ct-card--led .ct-frost-card .ct-quote,
  html body.home-page #clients #testimonials .ct-card--led .ct-frost-card .ct-mark,
  html body.home-page #clients #testimonials .ct-card--led .ct-frost-card .ct-name,
  html body.home-page #clients #testimonials .ct-card--led .ct-frost-card .ct-role,
  html body.home-page #clients #testimonials .ct-card--led .ct-frost-card .ct-company {
    color: var(--testimonials-card-ink, #10121a) !important;
  }

  /* The desktop card scrolls a long quote inside its own box. Inside a
     horizontal snap rail that gesture is unresolvable — a vertical drag on the
     quote is also a page scroll. Clamp instead, with an explicit control
     (mobile-motion.js) for the quotes that need one. */
  html body.home-page #clients #testimonials .ct-quote-block {
    flex: 0 1 auto;
    min-height: 0;
    max-height: none !important;
    padding-inline: 0;
    overflow: visible !important;
  }

  html body.home-page #clients #testimonials .ct-quote-block.is-scrollable::after {
    display: none !important;
  }

  html body.home-page #clients #testimonials .ct-card {
    --ct-quote-inset: 0px;
  }

  html body.home-page #clients #testimonials .ct-quote {
    display: -webkit-box;
    margin-inline: 0;
    padding-inline: 0;
    overflow: hidden;
    font-size: .875rem !important;
    line-height: 1.55 !important;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 6;
    line-clamp: 6;
  }

  html body.home-page #clients #testimonials .ct-mark {
    position: static;
    display: inline;
    margin-inline-end: .2em;
  }

  /* Same control as the project cards, so "there is more here" means one
     thing across the whole phone build — including the 44px tap box. It opens
     the quote dialog below rather than growing the card inside the rail. */
  html body.home-page #clients #testimonials .ct-quote-toggle {
    min-height: 2.75rem;
    display: inline-flex;
    align-items: center;
    margin-top: .25rem;
    color: inherit;
    font-size: .6875rem;
    font-weight: 500;
    letter-spacing: .12em;
    text-transform: uppercase;
    text-decoration: underline;
    text-underline-offset: .35em;
    cursor: pointer;
  }

  /* Attribution is the whole point of a testimonial — it was the part the old
     clamp cut off. It sits on the floor of the card, always visible. */
  html body.home-page #clients #testimonials .ct-card-foot {
    display: flex;
    align-items: flex-end;
    gap: 1rem;
    margin-top: auto;
    padding-top: 1.125rem;
  }

  html body.home-page #clients #testimonials .ct-meta {
    flex: 1 1 auto;
    align-items: flex-start;
    margin-inline: 0;
    padding-inline: 0;
    text-align: left;
  }

  html body.home-page #clients #testimonials .ct-name {
    margin-inline: 0;
    font-size: .8125rem;
    font-weight: 500;
    text-align: left;
  }

  html body.home-page #clients #testimonials .ct-role,
  html body.home-page #clients #testimonials .ct-company {
    margin-inline: 0;
    padding-inline: 0;
    font-size: .6875rem;
    line-height: 1.4;
    text-align: left;
  }

  html body.home-page #clients #testimonials .ct-logo {
    flex: 0 0 auto;
    align-self: flex-end;
  }

  html body.home-page #clients #testimonials .ct-logo img {
    width: auto;
    max-width: 4.5rem;
    max-height: 1.5rem;
    object-fit: contain;
  }

  /* Position readout, same component as the work and services decks. Those
     rails are full-bleed and the nav supplies its own gutter; this one already
     sits inside the clients layout padding. */
  html body.home-page #clients #testimonials .work-deck-nav {
    margin-top: .875rem;
    padding-inline: 0;
  }

  /* ── Quote dialog ─────────────────────────────────────────────────────────
     The card morphs into this sheet (mobile-motion.js builds and FLIPs it).
     It is its own component at body level rather than a grown card: the rail
     is 86% of a phone screen wide, which is the wrong measure for reading a
     long testimonial, and growing a card inside a mandatory-snap rail moves
     the section under the reader.

     The panel takes its surface, ink and radius from the card it came from,
     so whatever the CMS sets for the testimonial card is what opens. */
  .ct-dialog {
    position: fixed;
    inset: 0;
    /* Over the fixed header (800) and the nav band; under nothing. */
    z-index: 9600;
  }

  /* The scrim is the scroll lock. It covers the viewport, so every touch that
     is not on the sheet lands here and goes nowhere — no pinning of the body,
     which is what used to collapse the document to one screen and clamp the
     scroll to 0. The sheet keeps its own scrolling (pan-y below) and contains
     its overscroll, so nothing chains to the page. */
  .ct-dialog__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(8, 10, 14, .58);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
    touch-action: none;
  }

  .ct-dialog__panel {
    position: fixed;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    box-shadow: 0 1.5rem 4rem rgba(4, 7, 13, .38);
    /* The FLIP runs on this, from the card's rect. */
    transform-origin: 0 0;
    will-change: transform, opacity;
  }

  .ct-dialog__media {
    flex: 0 0 auto;
    width: 100%;
    height: 9.5rem;
    overflow: hidden;
  }

  .ct-dialog__media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  /* The one scrollable thing on screen while the dialog is open. */
  .ct-dialog__body {
    flex: 1 1 auto;
    padding: 1.25rem 1.25rem 1.5rem;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    touch-action: pan-y;
  }

  .ct-dialog__quote {
    margin: 0;
    font-size: .9375rem;
    line-height: 1.6;
  }

  .ct-dialog__mark {
    margin-inline-end: .2em;
  }

  .ct-dialog__foot {
    display: flex;
    align-items: flex-end;
    gap: 1rem;
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid currentColor;
    /* The rule is a hairline of the ink colour, not a second ink. */
    border-top-color: color-mix(in srgb, currentColor 18%, transparent);
  }

  .ct-dialog__meta {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-width: 0;
  }

  .ct-dialog__name {
    font-size: .875rem;
    font-weight: 500;
  }

  .ct-dialog__role,
  .ct-dialog__company {
    font-size: .6875rem;
    line-height: 1.4;
    opacity: .74;
  }

  .ct-dialog__logo {
    flex: 0 0 auto;
  }

  .ct-dialog__logo img {
    width: auto;
    max-width: 4.5rem;
    max-height: 1.5rem;
    object-fit: contain;
  }

  .ct-dialog__close {
    position: absolute;
    top: .5rem;
    right: .5rem;
    width: 2.75rem;
    height: 2.75rem;
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(8, 10, 14, .42);
    color: #fff;
    cursor: pointer;
  }

  .ct-dialog__close::before,
  .ct-dialog__close::after {
    content: "";
    position: absolute;
    width: 1rem;
    height: 1px;
    background: currentColor;
  }

  .ct-dialog__close::before { transform: rotate(45deg); }
  .ct-dialog__close::after { transform: rotate(-45deg); }


  body.home-page .sc-reach {
    min-height: 0;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 2.75rem;
    padding:
      max(var(--mobile-section-space), var(--persistent-nav-offset, 6.25rem))
      max(var(--mobile-gutter), env(safe-area-inset-right))
      var(--mobile-section-space)
      max(var(--mobile-gutter), env(safe-area-inset-left));
    scroll-margin-top: var(--persistent-nav-offset, 6.25rem);
  }

  body.home-page .sc-reach .reach-copy {
    order: 1;
    padding: 0;
  }

  body.home-page .sc-reach .reach-dot-map {
    order: 2;
    width: 100%;
  }

  body.home-page .sc-reach .reach-copy h2,
  body.home-page .sc-reach .reach-copy h2 [style*="font-size"] {
    max-width: 10ch;
    font-size: var(--mobile-section-headline) !important;
    line-height: .96 !important;
    letter-spacing: -.04em !important;
    text-wrap: balance;
  }

  html body.home-page .sc-reach .reach-copy h2.mobile-one-line-heading {
    width: max-content;
    max-width: none;
    font-size: clamp(1.125rem, 5.97vw, var(--mobile-section-headline)) !important;
    white-space: nowrap;
    text-wrap: nowrap;
  }

  body.home-page .sc-reach .reach-copy > p {
    max-width: 34ch;
    margin-top: 1.5rem;
    font-size: 1rem;
    line-height: 1.55;
  }

  body.home-page .sc-reach .reach-stats {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
    margin-top: 2rem;
  }

  body.home-page .sc-reach .reach-stats b {
    font-size: clamp(2rem, 9vw, 2.75rem);
  }

  /* These captions are sized clamp(8px, .66vw, 10px)-style: the vw term is a
     desktop measure and collapses to the floor on a phone, so the map legend
     was setting at 8px and the stat labels at 10. 11px is the floor for
     uppercase, letterspaced type that still has to be read at arm's length. */
  body.home-page .sc-reach .reach-stats small,
  body.home-page .sc-reach .dot-map-meta,
  body.home-page .sc-reach .dot-map-regions,
  body.home-page .contact-hub .contact-channel {
    font-size: .6875rem;
    letter-spacing: .12em;
  }

  body.home-page .sc-reach .dot-map-meta {
    gap: .25rem .75rem;
  }

  body.home-page .sc-reach .dot-map-stage {
    min-height: 13rem;
    padding-block: 1rem;
  }

  /* Everything above this point reads off a left margin. A centred closing
     block breaks that spine right where the user is deciding to act. */
  body.home-page .sc-contact {
    min-height: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2rem;
    padding:
      var(--mobile-section-space)
      max(var(--mobile-gutter), env(safe-area-inset-right))
      var(--mobile-section-space)
      max(var(--mobile-gutter), env(safe-area-inset-left));
    text-align: left;
  }

  body.home-page .sc-contact > * {
    width: 100%;
    max-width: 100%;
    text-align: left;
  }

  body.home-page .sc-contact .contact-h,
  body.home-page .sc-contact .contact-h [style*="font-size"] {
    max-width: 12ch;
    margin: 0;
    font-size: var(--mobile-section-headline) !important;
    line-height: .98 !important;
    letter-spacing: -.04em !important;
    text-align: left !important;
    text-wrap: balance;
  }

  body.home-page .sc-contact .contact-h .headline-keep,
  body.home-page .sc-contact .contact-h .headline-keep > span {
    display: inline-block;
    white-space: nowrap !important;
  }

  body.home-page .sc-contact .contact-actions {
    margin-top: 0 !important;
  }

  /* ── Site footer ──────────────────────────────────────────────────────────
     Shared by every page. Stacked in source order it ran ~1,400px: eight menu
     links, three contact rows and two addresses, each row a 44px tap target,
     over a photograph. Same content, half the height — the menu pairs off into
     two columns and the legal line runs inline. */

  /* Legal sits above the sitemap in the desktop composition because it is a
     right-hand column. Stacked, that puts the copyright before the menu. */
  #site-footer .foot-glass {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    padding: 1.25rem 1.125rem;
    /* .40 white over a photograph left the smallest type at roughly 3:1.
       The blur is also one of the more expensive things a phone GPU can be
       asked to hold while the page scrolls. */
    background: rgba(255, 255, 255, .82);
    -webkit-backdrop-filter: blur(12px) saturate(115%);
    backdrop-filter: blur(12px) saturate(115%);
  }

  #site-footer .foot-glass .foot-grid {
    order: 1;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 1.5rem 1rem;
  }

  #site-footer .foot-grid h4 {
    margin-bottom: .25rem;
    font-size: .75rem;
  }

  /* Six to eight links down one column is the tallest block in the footer and
     the least worth the space. */
  #site-footer .foot-menu {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: 1rem;
  }

  #site-footer .foot-menu h4 {
    grid-column: 1 / -1;
  }

  /* Two columns of 44px rows read as a list with air injected between the
     items. The links sit in their own grid cells with a full column of
     separation beside them, so a shorter row still isn't a crowded target. */
  #site-footer .foot-menu a {
    min-height: 2.25rem;
    line-height: 1.35;
  }

  #site-footer .foot-offices-col {
    grid-column: 1 / -1;
  }

  /* Two addresses and two clock chips set solid ran as one block of text. */
  #site-footer .foot-offices-body {
    gap: 1.5rem;
    line-height: 1.45;
  }

  #site-footer .foot-office {
    line-height: 1.45;
  }

  #site-footer .foot-office > a {
    display: block;
    min-height: 0;
    line-height: 1.45;
  }

  #site-footer .foot-offices-body strong {
    margin-bottom: .25rem;
    font-size: .9375rem;
  }

  #site-footer .foot-offices-body br + strong {
    margin-top: 1.25rem;
  }

  #site-footer .foot-local-time {
    margin-top: .5rem;
    padding: .25rem .5rem;
  }

  #site-footer .foot-local-time + strong {
    margin-top: 1.25rem;
  }

  /* Anchored to the panel, not to the offices column: stacked, that column is
     the LAST block in the footer, so the control that takes you back to the
     top sat at the bottom of the page. Top-right of the glass, on the Menu
     heading's line. The column has to stop being a positioning context first,
     or the button resolves against it and stays down there. */
  #site-footer .foot-offices-col {
    position: static;
  }

  #site-footer .foot-glass .foot-offices-col > .foot-top-btn,
  #site-footer .foot-top-btn {
    position: absolute;
    top: .625rem;
    right: .75rem;
    z-index: 2;
    background: rgba(255, 255, 255, .55);
    border-color: rgba(16, 16, 16, .18);
  }

  /* The 54px reserve existed to keep the heading clear of the button while it
     lived in this column. */
  #site-footer .foot-offices-col > h4 {
    padding-right: 0;
  }

  #site-footer .foot-glass .foot-legal-stack {
    order: 2;
    display: flex;
    flex-direction: column-reverse;
    gap: 1rem;
    padding-top: 1.25rem;
    border-top: 1px solid rgba(16, 16, 16, .14);
  }

  /* Policy links above the copyright: they are the two things in this block
     anyone actually goes looking for. */
  #site-footer .foot-legal {
    display: flex;
    flex-direction: column-reverse;
    align-items: flex-start;
    font-size: .8125rem;
  }

  #site-footer .foot-legal nav {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 0 1.25rem;
    margin-top: 0;
    margin-bottom: .25rem;
  }

  #site-footer .foot-brand-logo {
    width: 8.75rem;
    padding-top: 0;
  }

  body.home-page #site-footer {
    padding:
      1rem
      max(var(--mobile-gutter), env(safe-area-inset-right))
      max(1rem, env(safe-area-inset-bottom))
      max(var(--mobile-gutter), env(safe-area-inset-left)) !important;
  }

  body.home-page .contact-form-panel {
    margin-top: .5rem;
  }

  body.home-page .contact-form {
    padding: 1.125rem 1rem;
  }

  body.home-page .contact-form-head {
    margin-bottom: 1rem;
  }

  body.home-page .contact-form-close {
    width: 2.75rem;
    height: 2.75rem;
  }

  body.home-page .contact-form-grid {
    gap: .875rem;
  }

  body.home-page .contact-form label > span {
    margin-bottom: .25rem;
  }

  body.home-page .contact-form input,
  body.home-page .contact-form textarea {
    padding: .35rem 0 .55rem;
  }

  body.home-page .contact-form textarea {
    min-height: 4.5rem;
  }

  body.home-page .contact-message-prompt {
    min-height: 2.75rem;
    padding-block: .5rem;
  }

  body.home-page .contact-form-foot {
    gap: .75rem;
    margin-top: 1rem;
  }

  body.home-page #site-footer .foot-legal {
    gap: .5rem;
  }

  /* About: a composed cover with readable display type and no clipping. */
  body.about-page #top {
    height: auto;
    min-height: 0;
    overflow: hidden;
  }

  body.about-page #top .hero-content {
    min-height: 0;
    padding: calc(5.5rem + env(safe-area-inset-top)) var(--mobile-gutter) 0;
  }

  body.about-page .au-cover-copy {
    min-height: 0;
  }

  body.about-page #top .hero-headline-block {
    max-width: 100%;
    padding-top: 1.75rem;
  }

  body.about-page #top .hero-title,
  body.about-page #top .hero-title [style*="font-size"] {
    max-width: 8ch;
    font-size: clamp(3.45rem, 15.2vw, 4.1rem) !important;
    line-height: .88 !important;
    letter-spacing: -.04em !important;
    text-wrap: balance;
  }

  body.about-page #top .hero-title .au-line--lead {
    letter-spacing: -.04em;
  }

  /* The CMS field style for about.hero_headline_html targets .au-line itself,
     with !important, so the phone cap on .hero-title never reached the lines
     that actually set the type: they held the desktop 90px, wrapped to four
     lines, and the block ran 342px. Restating both properties here (at higher
     specificity than the injected rule) puts the headline back on the phone
     scale and keeps about-editorial's lead/subhead relationship. */
  body.about-page #top .hero-title .au-line,
  body.about-page #top .hero-title .au-line--lead,
  /* The words themselves live in CMS rich-text spans that carry their own
     per-selection font-size, so sizing the .au-line wrapper alone changed the
     box and nothing else. */
  body.about-page #top .hero-title .au-line--lead * {
    font-size: clamp(3.45rem, 15.2vw, 4.1rem) !important;
    line-height: .92 !important;
  }

  body.about-page #top .hero-title .au-line:not(.au-line--lead),
  body.about-page #top .hero-title .au-line:not(.au-line--lead) * {
    font-size: clamp(1.95rem, 8.5vw, 2.3rem) !important;
    line-height: 1.02 !important;
  }

  body.about-page #top .hero-title .au-line:not(.au-line--lead) {
    margin-top: .18em;
  }

  body.about-page .au-cover-art {
    margin-top: -1.5rem;
    transform: none;
  }

  body.about-page .au-cover-art img {
    height: min(124vw, 32rem);
    object-position: 50% 100%;
  }

  body.about-page .au-intro-copy {
    min-height: 0;
    padding-block: var(--mobile-section-space);
  }

  body.about-page .au-intro-copy .au-hero-body,
  body.about-page .au-intro-copy .au-hero-body [style*="font-size"] {
    max-width: 29ch;
    font-size: clamp(1.5rem, 6.8vw, 2rem) !important;
    line-height: 1.2 !important;
    letter-spacing: -.025em;
  }

  /* 34% white over a saturated multicolour photograph is a desktop effect: at
     that size the panel covers a large, mostly flat area of the image. On a
     phone the same panel sits over the busiest part of it and the statement —
     the one piece of copy the section exists for — was reading at roughly 2:1
     against a pink-and-orange blur. Opaque enough to read, still glass. */
  body.about-page .au-intro-copy-glass {
    padding: 1.25rem;
    border-color: rgba(255, 255, 255, .6);
    background: rgba(255, 255, 255, .86);
    -webkit-backdrop-filter: blur(14px) saturate(115%);
    backdrop-filter: blur(14px) saturate(115%);
    box-shadow: 0 1rem 2.5rem rgba(16, 16, 16, .12);
  }

  body.about-page .au-intro-copy-grid {
    padding-block: 3rem;
  }

  body.about-page .au-sequence {
    overflow: visible;
  }

  body.about-page .au-seq-stage {
    display: grid;
    gap: 2rem;
    min-height: 0;
    padding: var(--mobile-section-space) var(--mobile-gutter);
    overflow: visible;
  }

  body.about-page .au-seq-fade {
    position: relative;
    inset: auto;
    max-width: 14ch;
    font-size: clamp(2rem, 9vw, 2.75rem);
    line-height: 1.04;
  }

  body.about-page .au-seq-lower {
    position: relative;
    inset: auto;
    display: grid;
    gap: 1rem;
    padding: 0;
  }

  body.about-page .au-seq-reveal {
    aspect-ratio: 4 / 3;
    min-height: 0;
    opacity: 1 !important;
    clip-path: none !important;
    transform: none !important;
  }

  body.about-page .au-seq-reveal img {
    width: 100%;
    height: 100%;
    min-height: 0;
    object-fit: cover;
    clip-path: none !important;
  }

  body.about-page .au-studio-note {
    margin: 0;
    opacity: 1 !important;
    transform: none !important;
  }

  body.about-page .au-studio-note p {
    max-width: 31ch;
    font-size: 1rem;
    line-height: 1.5;
  }

  body.about-page .au-section {
    padding-block: var(--mobile-section-space);
  }

  body.about-page .au-body,
  body.about-page .au-idea-paragraph,
  body.about-page .au-bullets {
    font-size: 1rem;
    line-height: 1.55;
  }

  /* Project archive: title first, thumb-friendly filter rail, compact cards. */
  body.projects-page .proj-head {
    gap: 1.5rem;
    padding:
      calc(6.5rem + env(safe-area-inset-top))
      var(--mobile-gutter)
      2rem;
  }

  body.projects-page .proj-heading,
  body.projects-page .proj-heading [style*="font-size"] {
    max-width: 10ch;
    font-size: clamp(2.5rem, 11vw, 3.25rem) !important;
    line-height: .96 !important;
    letter-spacing: -.04em !important;
  }

  body.projects-page .proj-intro-p {
    max-width: 34ch;
    margin-top: 1rem;
    font-size: 1rem;
    line-height: 1.55;
  }

  /* Clamped by mobile-motion.js, which also builds the control. */
  body.projects-page .proj-intro-p.is-intro-clamped {
    display: -webkit-box;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 4;
    line-clamp: 4;
  }

  body.projects-page .proj-intro-more {
    display: inline-block;
    min-height: 2.75rem;
    margin-top: .5rem;
    padding: .75rem 0;
    border-bottom: 1px solid currentColor;
    font-size: .6875rem;
    font-weight: 500;
    letter-spacing: .12em;
    line-height: 1.25rem;
    text-transform: uppercase;
    cursor: pointer;
  }

  body.projects-page .proj-filters {
    width: calc(100vw - var(--mobile-gutter));
    max-width: none;
    flex-wrap: nowrap;
    gap: .5rem;
    padding-right: var(--mobile-gutter);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
  }

  body.projects-page .proj-filters::-webkit-scrollbar {
    display: none;
  }

  body.projects-page .proj-cap {
    min-height: 2.75rem;
    padding: .75rem 1rem;
    font-size: .75rem;
    scroll-snap-align: start;
  }

  body.projects-page .proj-section {
    padding: 0 var(--mobile-gutter) var(--mobile-section-space);
  }

  body.projects-page .proj-grid {
    gap: 1.25rem;
  }

  /* Padding is the only gutter the card has now: the media box carries the
     image's own ratio (--pj-ar), so this value is the equal left/top/right
     space between the white container and the picture. */
  body.projects-page .pj-card,
  body.projects-page .pj-card:nth-child(n) {
    --pj-pad: .75rem;
  }

  body.projects-page .pj-card .pj-info,
  body.projects-page .pj-card:last-child:nth-child(odd) .pj-info {
    padding: 1.125rem 0 0;
    gap: .75rem;
  }

  body.projects-page .pj-cat {
    font-size: .75rem;
    line-height: 1.45;
  }

  body.projects-page .pj-title {
    max-width: none;
    font-size: 1.125rem;
    line-height: 1.15;
    text-wrap: pretty;
  }

  body.projects-page .pj-more {
    min-height: 2.75rem;
    padding: .75rem .875rem;
    font-size: .6875rem;
  }

  /* Project detail: image-led opening, legible metadata, thumb-safe gallery. */
  body.portfolio-page .back-pill {
    min-height: 2.75rem;
    display: inline-flex;
    align-items: center;
    padding: .75rem;
    font-size: .59375rem;
    letter-spacing: .08em;
  }

  body.portfolio-page .nav-right,
  body.portfolio-page .nav-end {
    gap: .375rem;
  }

  body.portfolio-page .editorial-left {
    padding:
      calc(6.25rem + env(safe-area-inset-top))
      var(--mobile-gutter)
      2.5rem;
    gap: 2.5rem;
  }

  body.portfolio-page .editorial-feature {
    width: min(48vw, 11rem);
    max-width: none;
    margin-bottom: 1.5rem;
  }

  body.portfolio-page .editorial-title,
  body.portfolio-page .editorial-title [style*="font-size"] {
    max-width: 13ch;
    font-size: clamp(2.5rem, 11vw, 3.25rem) !important;
    line-height: 1 !important;
    letter-spacing: -.04em !important;
    text-wrap: balance;
  }

  body.portfolio-page .editorial-writeup,
  body.portfolio-page .editorial-writeup [style*="font-size"] {
    max-width: 34ch;
    margin-top: 1.25rem;
    font-size: 1rem !important;
    line-height: 1.55 !important;
  }

  /* Label left, value right is a two-column reading pattern. In 335px the
     values wrap to two and three lines and the right edge does the wrapping,
     so the middle of the block is ragged on both sides and nothing lines up
     with anything. Stacked and left-aligned, every row reads down one spine. */
  body.portfolio-page .meta-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: .125rem;
    padding: .75rem 0;
  }

  body.portfolio-page .meta-label {
    font-size: .6875rem;
    line-height: 1.35;
  }

  body.portfolio-page .meta-val {
    font-size: .875rem;
    line-height: 1.45;
    text-align: left;
  }

  body.portfolio-page .editorial-right {
    margin: 0 var(--mobile-gutter);
    aspect-ratio: 4 / 5;
  }

  body.portfolio-page .case-media,
  body.portfolio-page .gallery-video-wrap {
    margin-inline: var(--mobile-gutter);
  }

  body.portfolio-page .case-body {
    padding: var(--mobile-section-space) var(--mobile-gutter);
  }

  body.portfolio-page .case-body-text {
    max-width: 36ch;
    font-size: 1rem;
    line-height: 1.6;
  }

  body.portfolio-page .gallery-bento,
  body.portfolio-page .gallery-bento.is-arranged {
    grid-template-columns: 1fr;
    padding-inline: var(--mobile-gutter);
  }

  body.portfolio-page .gallery-bento .bi,
  body.portfolio-page .gallery-bento .bi[data-orientation="landscape"] {
    grid-column: 1;
  }

  body.portfolio-page .gallery-open::after {
    opacity: 1;
    transform: none;
  }

  body.portfolio-page .np-head {
    align-items: flex-start;
    flex-direction: column;
    gap: 1.25rem;
    padding-inline: var(--mobile-gutter);
  }

  body.portfolio-page .np-right {
    width: 100%;
    justify-content: space-between;
  }

  body.portfolio-page .np-btn,
  body.portfolio-page .np-all {
    min-width: 2.75rem;
    min-height: 2.75rem;
  }

  body.portfolio-page .np-grid {
    margin-inline: var(--mobile-gutter);
  }

  body.portfolio-page .np-card {
    flex-basis: min(82vw, 20rem);
  }

  /* The category is right-aligned because the desktop rail runs three cards
     across and the label balances the name at the other end of a narrow card.
     One card wide, it left the label stranded at the far edge of the screen,
     reading as a caption for nothing. */
  body.portfolio-page .np-card-foot {
    justify-content: flex-start;
    min-height: 0;
  }

  body.portfolio-page .np-card-category {
    max-width: 100%;
    font-size: .6875rem;
    text-align: left;
  }

  /* 176px of closing padding under a rail that already ends the page. */
  body.portfolio-page .next-projects {
    padding-bottom: var(--mobile-section-space);
  }

  /* Legal and dynamic content pages: reading sizes and controls. */
  body.legal-page .hero,
  body.dynamic-page .wrap {
    padding-left: var(--mobile-gutter);
    padding-right: var(--mobile-gutter);
  }

  body.legal-page .hero {
    padding-top: calc(7rem + env(safe-area-inset-top));
    padding-bottom: 3.5rem;
  }

  body.legal-page .hero h1 {
    font-size: clamp(2.5rem, 11vw, 3.25rem);
    line-height: 1;
    letter-spacing: -.04em;
  }

  body.legal-page .hero .intro {
    max-width: 34ch;
    font-size: 1rem;
    line-height: 1.55;
  }

  body.legal-page .tabs a {
    min-height: 2.75rem;
    display: inline-flex;
    align-items: center;
  }

  body.legal-page .content p,
  body.legal-page .content li {
    font-size: 1rem;
    line-height: 1.65;
  }

  body.dynamic-page .wrap {
    padding-top: calc(7rem + env(safe-area-inset-top));
    padding-bottom: var(--mobile-section-space);
  }

  body.dynamic-page .lead,
  body.dynamic-page .block {
    font-size: 1rem;
    line-height: 1.6;
  }

  body.dynamic-page .block {
    margin-bottom: 1.5rem;
    padding: 1.375rem;
  }

  /* The page's own clamp() floors this span at 18px, which lands under the
     body copy on a phone. Let the CMS-editable span inherit the h1 scale. */
  body.projects-page .proj-heading [data-cms],
  body.projects-page .proj-heading [data-cms-html],
  body.projects-page .proj-heading [data-cms-src] {
    font-size: inherit !important;
    line-height: inherit !important;
    letter-spacing: inherit !important;
  }

  body.not-found-page .not-found__message a {
    min-height: 2.75rem;
    display: inline-flex;
    align-items: center;
  }

  /* ── Articles, FAQ, and the homepage journal deck ─────────────────────────
     knowledge-pages.css is an editorial layout: a magazine masthead that holds
     the title down the page and captions set at desktop distances. Both need
     phone numbers. */

  /* 44rem of hero with the title bottom-aligned inside it left the whole first
     screen empty above "Articles". The masthead gesture survives at 30. */
  body.blog-page .kp-magazine-hero {
    min-height: 30rem;
    padding-block: 6.5rem 2rem;
  }

  body.blog-page .kp-magazine-heading {
    gap: 2rem;
    padding-top: 2rem;
  }

  /* The shared readout pulls itself up by 8px, which works under a rail whose
     cards end in flat paper. The journal cards end in a full-bleed photograph,
     so the dots were landing inside the artwork. */
  body.home-page .home-journal .work-deck-nav {
    margin-top: 1rem;
  }

  /* 0.72vw floors these at 10px on a desktop and resolves to under 9 here —
     under the 11px that stays legible at arm's length on a phone. */
  .knowledge-page .kp-meta,
  .knowledge-page .kp-filter,
  .knowledge-page .kp-card-link,
  .knowledge-page .kp-back,
  .knowledge-page .kp-featured__label,
  .knowledge-page .kp-article__next-label,
  .knowledge-page .kp-magazine-strap,
  .home-journal .kp-meta,
  .home-journal__link,
  .home-journal__cover-link,
  .home-journal time,
  .home-journal .home-journal__meta,
  .home-journal .home-journal__meta * {
    font-size: .6875rem;
    letter-spacing: .1em;
  }

  /* A chip rail cut flush at the gutter reads as clipped rather than
     scrollable. mobile-motion.js measures which rails actually overflow — a
     fade on a row that already fits is a lie about there being more. */
  [data-rail-overflow="1"] {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 2.25rem), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 2.25rem), transparent);
  }

  /* Paragraph break inside a long CMS field — see applyStanzas() in
     mobile-motion.js. Sized off the copy's own line-height so the rhythm holds
     whatever size the CMS sets. */
  .mrv-stanza-break {
    display: block;
    height: .85em;
    content: "";
  }

  /* ── Scroll reveal ────────────────────────────────────────────────────────
     Position triggers the block, then it plays on its own fixed duration —
     never scrubbed by finger speed. mobile-motion.js tags the roots and only
     turns the layer on once it has (so a JS failure can never hide content).

     The :not(.is-mrv-in) + !important pair is deliberate: this layer sits on
     top of the flatten-the-desktop-pin rules above, several of which pin
     opacity to 1 !important to defeat the scrub choreography. */
  /* No blur. Thirty of these are pending at any time on the homepage, and a
     transitioning blur is the most expensive thing a phone GPU can be asked to
     do while the user is dragging the page — it was the difference between the
     homepage and the inner pages. The fade and the rise carry the reveal. */
  html.mrv-on body [data-mrv]:not(.is-mrv-in) {
    opacity: 0 !important;
    transform: translate3d(0, .875rem, 0) !important;
  }

  html.mrv-on body [data-mrv] {
    transition:
      opacity .58s var(--mobile-ease) var(--mrv-delay, 0ms),
      transform .58s var(--mobile-ease) var(--mrv-delay, 0ms);
  }

  /* ── Compositor budget ────────────────────────────────────────────────────
     These carry will-change for desktop scroll choreography a phone never
     runs: the manifesto is painted static here and the archive mosaic is
     replaced by the deck's closing panel. That was 91 promoted layers — 57 of
     them individual words, one of which also declares
     font-variation-settings, so the text re-rasterises — for motion that
     cannot happen. mobile-motion.js still sets its own will-change inline on
     the elements it is about to animate, and inline wins over this. */
  body.home-page .oj-mw,
  body.home-page .work-archive__mosaic-cell,
  body.home-page .intro-bridge-moving-title,
  body.home-page .intro-bridge-exit-left,
  body.home-page .intro-bridge-exit-right,
  body.home-page .intro-bridge-word,
  body.home-page .intro-bridge-toggle-knob,
  body.home-page .hero-splash,
  body.home-page .hero-scrim,
  body.home-page .au-seq-stage,
  body.home-page .au-seq-title,
  body.home-page .au-seq-sub {
    will-change: auto;
  }
}

/* Portrait tablets keep richer grids but use content-led vertical rhythm. */
@media (min-width: 768px) and (max-width: 1023px) and (orientation: portrait) {
  header#header .nav,
  header.topbar .nav {
    padding-inline: clamp(2rem, 5vw, 3rem);
  }

  body.home-page .sc-reach {
    grid-template-columns: 1fr;
    min-height: 0;
    padding-block: clamp(4rem, 8vh, 6rem);
  }

  body.home-page .sc-reach .reach-copy {
    grid-row: 1;
    padding-left: 0;
  }

  body.home-page .sc-reach .reach-dot-map {
    grid-row: 2;
  }

  body.about-page #top .hero-title,
  body.about-page #top .hero-title [style*="font-size"] {
    max-width: 9ch;
    font-size: clamp(4.75rem, 11vw, 6.5rem) !important;
    letter-spacing: -.04em !important;
  }

  body.projects-page .proj-cap,
  body.portfolio-page .back-pill,
  body.portfolio-page .np-btn,
  body.portfolio-page .np-all {
    min-height: 2.75rem;
  }
}

@media (min-width: 768px) and (max-width: 1200px) and (orientation: landscape) {
  header#header .brand,
  header.topbar .brand,
  .menu a.m-link,
  .menu .nav-cta {
    min-height: 2.75rem;
    display: inline-flex;
    align-items: center;
  }

  .burger,
  .js-carousel__button--prev,
  .js-carousel__button--next {
    min-width: 2.75rem;
    min-height: 2.75rem;
  }

  #site-footer .foot-grid a,
  #site-footer .foot-legal nav a {
    min-height: 2.75rem;
    display: flex;
    align-items: center;
  }
}

@media (max-width: 359px) {
  html body.home-page #organism-numbers .oj-number-head h2.mobile-three-line-heading {
    font-size: 1.0625rem !important;
  }

  html body.home-page #top .hero-title,
  html body.home-page #top .hero-title [style*="font-size"] {
    max-width: 100%;
    font-size: clamp(2.15rem, 10.8vw, 2.35rem) !important;
    letter-spacing: -.045em !important;
  }
}

@media (max-width: 767px) {
  body.home-page .intro-bridge-exit-left {
    align-items: center;
    gap: .5rem;
  }

  body.home-page .intro-bridge-accent-wrap--mobile {
    display: block;
    width: 2.9rem;
    height: 1.55rem;
    margin: 0;
    align-self: center;
  }

  html.organism-motion body.home-page .intro-bridge-toggle-track.is-ready,
  html.organism-motion body.home-page .intro-bridge-toggle-track.is-ready .intro-bridge-toggle-knob {
    transition: none;
  }
}

@media (hover: none) {
  .work-card:hover .work-card__media img,
  .pj-card:hover .pj-img img,
  .np-card:hover .np-card-img img,
  .bi:hover img {
    transform: none !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  html.mrv-on body [data-mrv],
  html.mrv-on body [data-mrv]:not(.is-mrv-in) {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    transition: none !important;
    will-change: auto;
  }

  body.home-page .oj-manifesto-copy .oj-mw {
    transform: none !important;
    transition: none !important;
  }
}
