/* =========================================
   Ready Hit Play — Dial Styles (Barba-aware)
   - Scoped by data-dial-ns attribute (set by JS) for dial layout
   - [data-barba="wrapper"]:has() selectors still used for wrapper-level rules
   - Shared dial styles for home + work
   ========================================= */

/* Always hide scrollbar — Lenis/CSS scroll lock toggles overflow:auto/hidden
   which causes layout jumps when the scrollbar appears/disappears. */
html, body {
  scrollbar-width: none;          /* Firefox */
}
html::-webkit-scrollbar,
body::-webkit-scrollbar {
  display: none;                  /* Chrome, Safari, Edge */
}

   html { font-size: calc(0.7416576964477932rem + 0.21528525296017226vw); }
   @media screen and (max-width:1920px) { html { font-size: calc(0.7416576964477933rem + 0.21528525296017226vw); } }
   @media screen and (max-width:991px) { html { font-size: calc(0.85rem + 0.25vw); } }

/* Hide Webflow CMS empty-field placeholder images (403 SVG → iOS "?" icon) */
.w-dyn-bind-empty {
  display: none !important;
}

/* Hide nav items on home until home-scroll-morph completes and sets .rhp-home-ready.
   Cursor + dial ticks are visible from the first frame; nav items + step text
   stay hidden until the 100vh scroll-morph scrub completes and the wrapper
   gets .rhp-home-ready (home-scroll-morph._applyCompleteState). Until then
   the page shows #interactive-logo in .home-intro_middle and the small
   .home-transition-dial in .home-intro_bottom. */
[data-barba="wrapper"]:has([data-barba-namespace="home"]):not(.rhp-home-ready) .nav_logo-link,
[data-barba="wrapper"]:has([data-barba-namespace="home"]):not(.rhp-home-ready) .nav_about-link,
[data-barba="wrapper"]:has([data-barba-namespace="home"]):not(.rhp-home-ready) .nav_contact-link {
  opacity: 0 !important;
  visibility: hidden !important;
  pointer-events: none !important;
}

/* Step text stays hidden during the home intro scrub — home-scroll-morph
   tweens it to opacity:1 in the last 10% of the scrub. This CSS rule covers
   the gap between first paint and scripts loading so the step text never
   flashes visible in the dial-small state. */
[data-barba="wrapper"]:has([data-barba-namespace="home"]):not(.rhp-home-ready) .dial_component[data-dial-ns="home"] .heading-style-h7.is-step,
[data-barba="wrapper"]:has([data-barba-namespace="home"]):not(.rhp-home-ready) .dial_component[data-dial-ns="home"] [data-text="step"] {
  opacity: 0 !important;
  visibility: hidden;
  pointer-events: none;
}

/* Page loader — visible until init.js adds .rhp-scripts-loaded to <html>.
   Inline <style> in init.js covers the gap before this CSS loads.
   .loader MUST be position:fixed so it never affects document flow / ScrollTrigger. */
.loader {
  position: fixed !important;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none !important;
  z-index: 9999;
}

.loader4_component {
  pointer-events: none !important;
  opacity: 0;
  animation: rhp-loader-fadein 0.3s ease 0.5s forwards;
}

@keyframes rhp-loader-fadein {
  to { opacity: 1; }
}

.loader4_progress-bar {
  width: 0;
  animation: rhp-loader-fill 12s cubic-bezier(0.1, 0.4, 0.2, 1) forwards;
}

/* Scripts ready: hide loader instantly */
.rhp-scripts-loaded .loader,
.rhp-scripts-loaded .loader4_component {
  display: none !important;
}

@keyframes rhp-loader-fill {
  0%   { width: 0; }
  70%  { width: 55%; }
  90%  { width: 75%; }
  100% { width: 85%; }
}

@media (prefers-reduced-motion: reduce) {
  .loader4_progress-bar {
    animation: none;
  }
  .rhp-scripts-loaded .loader,
  .rhp-scripts-loaded .loader4_component {
    transition: none;
  }
}

/* Hide nav completely on About page (not visible, not clickable) */
[data-barba="wrapper"].rhp-nav-hidden .nav {
  display: none !important;
  pointer-events: none;
  visibility: hidden;
}

/* When entering home (about→home or case→home), show nav even if rhp-nav-hidden was not yet removed (override timing/order) */
[data-barba="wrapper"]:has([data-barba-namespace="home"]).rhp-home-ready .nav {
  display: flex !important;
  pointer-events: auto;
  visibility: visible;
}

/* About hero: static final-state (no JS hover/scroll anim on this element anymore).
   home-about-slide.js owns the whole about page container entry/exit — the hero
   logo is just a static layout element now. */
.section_about-hero .about-hero_ready {
  opacity: 1;
  transform: none;
  filter: none;
}

/* Video cover: fill container on any page */
.video-cover {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* About → Home transition: nav logo end position (top of viewport; 2vh default, 3rem at 1920+) */
:root {
  --nav-logo-return-top: 2vh;
  --nav-logo-return-embed-height: 2rem;
  /* Target size for #transition-logo when animating to match about hero logo (home → about) */
  --about-hero-logo-width: min(70vw, 37.5rem);
  --about-hero-logo-height: auto;
}

/* Logo size variables: logo large (about hero) and logo small (nav). Override per breakpoint below. */
:root {
  --logo-large-width: 90vw;
  --logo-large-height: auto;
  --logo-large-max-width: 93rem;
  --logo-small-width: 16rem;
  --logo-small-height: 2rem;
}

/* Apply logo large to .nav_logo-wrapper-2 (about hero, transition target) */
.nav_logo-wrapper-2 {
  width: var(--logo-large-width);
  height: var(--logo-large-height);
  max-width: var(--logo-large-max-width);
}

/* Apply logo small to nav; .is-nav overrides the large defaults */
.nav_logo-wrapper-2.is-nav {
  width: var(--logo-small-width);
  height: var(--logo-small-height);
  max-width: none;
}

/* When Flip reparents logo into _logo-middle (about position), override .is-nav
   to use large size. Flip reads this CSS end-state and animates from small → large. */
.about-transition_logo-middle .nav_logo-wrapper-2.is-nav {
  width: var(--logo-large-width);
  height: var(--logo-large-height);
  max-width: var(--logo-large-max-width);
}

/* SVGs inside the large-state transition logo need width:100% height:auto
   (same as the about-hero rules) to fill the container proportionally. */
.about-transition_logo-middle .nav_logo-wrapper-2.is-nav .about-hero_ready,
.about-transition_logo-middle .nav_logo-wrapper-2.is-nav .nav_logo-embed {
  height: auto;
}
.about-transition_logo-middle .nav_logo-wrapper-2.is-nav svg {
  width: 100%;
  height: auto;
}

/* Nav logo: use the same width-driven flex layout as the interactive logo
   so a uniform GSAP scale produces a pixel-perfect match. The nav wrapper's
   fixed width (--logo-small-width) constrains the flex children; height
   follows from SVG aspect ratio. Removing height:100% avoids Safari's
   SVG height="162" attribute override — the proportional flex handles sizing. */
.nav_logo-wrapper-2.is-nav .about-hero_ready,
.nav_logo-wrapper-2.is-nav .nav_logo-embed {
  height: auto;
}
.nav_logo-wrapper-2.is-nav svg {
  width: 100%;
  height: auto;
}

/* Logo proportional flex: distribute widths by each SVG's viewBox width
   (602, 316, 494) so all three words render at identical height.
   Applies to both the about hero AND the transition overlay logo
   (GSAP animates the transition logo to height:auto — SVGs need
   CSS height:auto to override the HTML height="100%" attribute,
   otherwise auto resolves to ~0 and the logo collapses). */
.nav_logo-wrapper-2 > .about-hero_ready:nth-child(1),
#interactive-logo > .about-hero_ready:nth-child(1) { flex: 602 1 0%; }
.nav_logo-wrapper-2 > .about-hero_ready:nth-child(2),
#interactive-logo > .about-hero_ready:nth-child(2) { flex: 316 1 0%; }
.nav_logo-wrapper-2 > .about-hero_ready:nth-child(3),
#interactive-logo > .about-hero_ready:nth-child(3) { flex: 494 1 0%; }

.nav_logo-wrapper-2 svg,
#interactive-logo svg {
  width: 100%;
  height: auto;
}

/* Breakpoint overrides: edit logo sizes per viewport (Webflow breakpoints: 991px, 767px, 479px) */
@media screen and (max-width: 991px) {
  :root {
    --logo-large-width: 90vw;
    --logo-large-height: auto;
    --logo-large-max-width: 93rem;
    --logo-small-width: 16rem;
    --logo-small-height: 2rem;
  }
  /* Remove Webflow backdrop blur on nav logo */
  .nav_logo-embed {
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
}

@media screen and (max-width: 767px) {
  :root {
    --logo-large-width: 90vw;
    --logo-large-height: auto;
    --logo-large-max-width: 93rem;
    /* Smaller nav logo: ~1.25rem height, ~11.4rem width (scales with fluid rem) */
    --logo-small-width: 11.4rem;
    --logo-small-height: 1.25rem;
  }
}

@media screen and (max-width: 479px) {
  :root {
    --logo-large-width: 90vw;
    --logo-large-height: auto;
    --logo-large-max-width: 93rem;
    --logo-small-width: 11.4rem;
    --logo-small-height: 1.25rem;
  }
}

/* About team hover: name shift when a member is hovered/tapped. Editable by breakpoint. */
:root {
  --team-name-shift: 4rem;
}
@media screen and (max-width: 991px) {
  :root { --team-name-shift: 3.5rem; }
}
@media screen and (max-width: 767px) {
  :root { --team-name-shift: 3rem; }
}
@media screen and (max-width: 479px) {
  :root { --team-name-shift: 2rem; }
}

/* Transition dial position (home → about): distance from bottom of viewport; x-offset nudges final position (negative = left). Editable by breakpoint. */
:root {
  --transition-dial-bottom: 2rem;
  --transition-dial-x-offset: -4px;
}
@media screen and (min-width: 1920px) {
  :root {
    --transition-dial-bottom: max(2vh, 3rem);
    --nav-logo-return-top: 3rem;
  }
}
@media screen and (max-width: 991px) {
  :root {
    --transition-dial-bottom: 2rem;
  }
}
@media screen and (max-width: 767px) {
  :root {
    --transition-dial-bottom: 2rem;
  }
}
@media screen and (max-width: 479px) {
  :root {
    --transition-dial-bottom: 2rem;
  }
}

/* Hide native cursor everywhere when custom cursor is active */
[data-barba="wrapper"].rhp-cursor-ready,
[data-barba="wrapper"].rhp-cursor-ready *,
[data-barba="wrapper"].rhp-cursor-ready .dial_component {
  cursor: none !important;
}

/* ====== Stage (shared home + work + about) ====== */
.dial_component[data-dial-ns="home"],
.dial_component[data-dial-ns="work"],
.dial_component[data-dial-ns="about"] {
  position: relative;
  width: 100%;
  height: 100dvh;
  overflow: hidden;
  display: grid;
  place-items: center;
  -webkit-tap-highlight-color: transparent;
  touch-action: none; /* we manage gestures for the dial */
}

/* Mobile: JS freezes height to window.innerHeight after morph complete
   (immune to dvh/lvh browser-bar fluctuations). During intro, 100dvh
   matches the visible viewport with browser bar showing. */

@supports not (height: 100dvh) {
  .dial_component[data-dial-ns="home"],
  .dial_component[data-dial-ns="work"],
  .dial_component[data-dial-ns="about"] {
    height: 100vh;
  }
}

/* NOTE:
   The old page-level CSS had html/body overflow + height rules for scroll locking.
   Scroll locking is now handled in JS (RHP.scroll + Lenis), so we intentionally
   do NOT include those global html/body rules here. */

/* ====== Layers (shared) ====== */
.dial_component[data-dial-ns="home"] .dial_layer-bg,
.dial_component[data-dial-ns="work"] .dial_layer-bg,
.dial_component[data-dial-ns="about"] .dial_layer-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.dial_bg-canvas {
  width: 100%;
  height: 100%;
  display: block;
}

.dial_component[data-dial-ns="home"] .dial_bg-canvas,
.dial_component[data-dial-ns="work"] .dial_bg-canvas,
.dial_component[data-dial-ns="about"] .dial_bg-canvas {
  width: 100%;
  height: 100%;
  display: block;
  transform: scale(1.1);
}

/* Home: blur(0) default; GSAP animates to blur(40px) on .dial_layer-fg hover (desktop) */
.dial_component[data-dial-ns="home"] .dial_bg-canvas {
  filter: blur(0px);
}

/* Work/about: always blurred from click-through until return to home */
.dial_component[data-dial-ns="work"] .dial_bg-canvas,
.dial_component[data-dial-ns="about"] .dial_bg-canvas {
  filter: blur(40px);
}

/* About: hide background canvas */
.dial_component[data-dial-ns="about"] .dial_bg-canvas {
  display: none;
}

/* About: hide fg-video (persists from home visit; prevents flash during about→home slide) */
.dial_component[data-dial-ns="about"] #fg-video-wrap {
  opacity: 0;
  visibility: hidden;
}

/* Canvas ticks — full size; tick radius comes from fgWrap in JS (max 50svh × 70vw via video wrap) */
/* Scope to dial_component only — about page uses .about_dial-wrapper with different layout */
.dial_component[data-dial-ns="home"] .dial_layer-ticks,
.dial_component[data-dial-ns="work"] .dial_layer-ticks,
.dial_component[data-dial-ns="about"] .dial_layer-ticks {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  pointer-events: none;
  transform-origin: 50% 50%;
  will-change: transform;
}

/* Foreground circle — home: uses --dial-live-width/height, which
   home-scroll-morph.js scrubs between --dial-small-* and --dial-large-*.
   Fallback to --dial-large-* if the live vars were never set (post-morph
   steady state or no-JS environment). */
.dial_component[data-dial-ns="home"] .dial_layer-fg {
  position: absolute;
  inset: 0;
  margin: auto;
  width: var(--dial-live-width, var(--dial-large-width));
  height: var(--dial-live-height, var(--dial-large-height));
  display: grid;
  place-items: center;
  z-index: 3;
}

/* Initial intro state: dial sized small, ticks hidden. Applied as a class
   so it survives any inline-style clearing by GSAP/IX2 at page load. Removed
   by home-scroll-morph.js once the scrub completes. The transition dial in
   .home-transition provides the visible teal ticks during the intro.
   Only the ticks canvas is hidden — the generic (idle) video stays visible
   as a background behind the intro overlay. */
.dial_component.is-intro-small {
  --dial-live-width: var(--dial-small-width);
  --dial-live-height: var(--dial-small-height);
}
.dial_component.is-intro-small #dial_ticks-canvas {
  opacity: 0 !important;
}

/* Desktop: home starts at opacity 0; GSAP animates to 1 on .dial_layer-fg hover.
   Case/about: always opacity 1 from click-through until return to home. */
@media (hover: hover) {
  .dial_component[data-dial-ns="home"] .dial_layer-fg {
    opacity: 0;
  }
  .dial_component[data-dial-ns="work"] .dial_layer-fg,
  .dial_component[data-dial-ns="about"] .dial_layer-fg {
    opacity: 1;
  }
}

/* Mobile: hide fg layer on home until ACTIVE state (JS sets opacity:1 via setDialState).
   Desktop uses @media (hover: hover) above; mobile needs an explicit rule because
   hover:none devices don't match the desktop media query. */
@media (hover: none), (pointer: coarse) {
  .dial_component[data-dial-ns="home"] .dial_layer-fg {
    opacity: 0;
  }
}

.dial_component[data-dial-ns="work"] .dial_layer-fg,
.dial_component[data-dial-ns="about"] .dial_layer-fg {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  z-index: 3;
  /* Safari: place-items on grid doesn't reliably center absolute children.
     Explicit margin:auto + inset:0 is the cross-browser centering pattern. */
  margin: auto;
  /* pointer-events are managed in JS / via dial interaction */
}

/* Default: circular (home) — fills dial_layer-fg which is clamped to max 50svh × 70vw */
.dial_video-wrap {
  width: 100%;
  height: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 999px;
  overflow: hidden;
}

/* Dial size variables: dial-large (homepage), dial-small (about). Editable by breakpoint. */
:root {
  --dial-large-width: clamp(180px, min(50svh, 70vw), min(50svh, 70vw));
  --dial-large-height: clamp(180px, min(50svh, 70vw), min(50svh, 70vw));
  --dial-small-width: 6rem;
  --dial-small-height: 6rem;
}

/* =========================================
   Home intro section + logo slot
   - Only visible inside the home Barba namespace (defensive — the symbol
     may appear in other namespaces via Webflow symbols).
   - home-scroll-morph.js scrubs the dial size over the intro section height
     and tweens the real .nav_logo-wrapper-2 (without .is-nav) toward the
     nav target.
   - At morph complete the module sets display:none on this section so it
     stops taking layout room.
   ========================================= */
.section_home-intro {
  display: none;
}
/* Scope via :has() so the section can live as a sibling of .section_home inside
   main.main-wrapper (keeps the Webflow page layout clean) instead of being
   forced inside the Barba container. When Barba swaps the container namespace
   to about/case, the :has() check stops matching and the section reverts to
   display: none — no cross-namespace leak. */
main.main-wrapper:has([data-barba="container"][data-barba-namespace="home"]) .section_home-intro {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100svh;
  min-height: 100svh;
  position: relative;
  z-index: 2;
  /* Explicit override: the older deployed ready-hit-play.css (pinned in the
     Webflow head <link>) sets pointer-events:none here. We now need hover on
     the intro logo, so force auto. Harmless once the CDN catches up. */
  pointer-events: auto;
}

/* Reverted 2026-05-04: was 300svh + fixed positioning for scroll-driven word reveal.
   Now 100svh with timed word cycle. See git history to restore. */

/* New: intro layout slots (home-scroll-morph.js uses Flip.fit to animate
   #interactive-logo from .home-intro_middle → .home-intro_top and
   .home-transition-dial from .home-intro_bottom → .home-intro_middle) */
.home-intro_top {
  position: absolute;
  top: 2rem;
  left: 50%;
  transform: translateX(-50%);
  width: var(--logo-small-width, 16rem);
}

.home-intro_middle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}

.home-intro_bottom {
  position: absolute;
  bottom: 2rem;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
}


.home-transition-dial {
  position: relative;
  overflow: visible;
  width: var(--dial-small-width, 6rem);
  height: var(--dial-small-height, 6rem);
}

#interactive-logo {
  width: var(--logo-large-width, 90vw);
  max-width: var(--logo-large-max-width, 93rem);
  opacity: 0; /* FOUC guard — JS fades in after init */
}
/* Spacers are only needed during the hover text reveal animation.
   Hidden by default so the interactive logo matches the nav logo structure. */
#interactive-logo .about_logo-spacer { display: none; }

/* REMOVED 2026-04-13: short-viewport laptop dial bump no longer needed.
   Leaving commented out for reference until next deploy confirms no regression.
@media (min-width: 1440px) and (max-width: 1990px) and (max-height: 849px) {
  :root {
    --dial-large-width: 63svh;
    --dial-large-height: 63svh;
  }
}
*/

/* CSS Custom Properties for GSAP animations (responsive) */
:root {
  /* Home state values — alias to dial-large so GSAP/orchestrator keep working */
  --dial-home-width: var(--dial-large-width);
  --dial-home-height: var(--dial-large-height);
  --dial-home-border-radius: 1000rem;
  --dial-home-aspect-ratio: 1;
  
  /* Case-study state values */
  --dial-case-width: 78vw;
  --dial-case-height: 85dvh;
  --dial-case-border-radius: 2.5rem; /* desktop */
  --dial-case-aspect-ratio: auto;
  --dial-case-title-gap: 140px; /* desktop */
}

/* Breakpoint overrides: dial-large and dial-small (values same across all mobile breakpoints) */
@media (max-width: 991px) {
  :root {
    --dial-large-width: min(65vw, 65svh);
    --dial-large-height: min(65vw, 65svh);
    --dial-small-width: 6rem;
    --dial-small-height: 6rem;
  }
}

/* Responsive breakpoints - case-study only (home uses dial-large) */
@media (max-width: 991px) {
  :root {
    --dial-case-width: 90vw;
    --dial-case-height: 80dvh;
    --dial-case-border-radius: 2.5rem; /* tablet */
    --dial-case-title-gap: 120px;
  }
}

@media (max-width: 767px) {
  :root {
    --dial-case-width: 95vw;
    --dial-case-height: 75dvh;
    --dial-case-border-radius: 5rem; /* mobile landscape */
    --dial-case-title-gap: 100px;
  }
}

@media (max-width: 479px) {
  :root {
    --dial-case-border-radius: 5rem; /* mobile portrait */
    --dial-case-title-gap: 80px;
  }
}

#fg-video-wrap.is-case-study {
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--dial-case-border-radius) var(--dial-case-border-radius) 0 0;
}

/* Fallback: namespace-based (for initial load before JS runs) */
.dial_component[data-dial-ns="home"] #fg-video-wrap {
  position: relative;
  width: 100%;
  height: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 999px;
  overflow: hidden;
}

.dial_component[data-dial-ns="work"] #fg-video-wrap,
.dial_component[data-dial-ns="about"] #fg-video-wrap {
  width: 100%;
  height: calc(var(--dial-case-height) - var(--dial-case-title-gap));
  max-height: none;
  border-radius: var(--dial-case-border-radius) var(--dial-case-border-radius) 0 0;
  overflow: hidden;
  flex-shrink: 0;
}

/* Work namespace: video wraps inside Barba container get no border-radius (reset from base .dial_video-wrap) */
[data-barba-namespace="work"] .dial_video-wrap {
  border-radius: 0;
}

/* CSS transitions removed - using GSAP for animations */

.dial_fg-video,
.dial_generic-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* iOS Safari shows a ? placeholder on empty/loading video elements.
     color:transparent hides text-based placeholders; the pseudo-element
     selectors hide the native WebKit play/poster overlay icon. */
  color: transparent;
  -webkit-text-fill-color: transparent;
}
/* Nuclear iOS Safari: suppress ALL native video chrome (the "?" no-media icon) */
.dial_component video::-webkit-media-controls,
.dial_component video::-webkit-media-controls-panel,
.dial_component video::-webkit-media-controls-container,
.dial_component video::-webkit-media-controls-start-playback-button,
.dial_component video::-webkit-media-controls-play-button,
.dial_component video::-webkit-media-controls-overlay-play-button,
.dial_component video::-webkit-media-text-track-display {
  display: none !important;
  -webkit-appearance: none !important;
  opacity: 0 !important;
  visibility: hidden !important;
  width: 0 !important;
  height: 0 !important;
  position: absolute !important;
  overflow: hidden !important;
}

/* ====== Labels (home only) ====== */
/* ScrambleText takes over: step text shows project name in ACTIVE state,
   dial_layer-ui no longer needed. Hidden on home. */
.dial_component[data-dial-ns="home"] .dial_layer-ui {
  display: none;
}

/* Step text must sit above .dial_layer-fg (z-index 3) so the scrambled project name
   stays visible when the foreground video fades in during ACTIVE state. */
.dial_component[data-dial-ns="home"] .heading-style-h7.is-step,
.dial_component[data-dial-ns="home"] [data-text="step"] {
  z-index: 5;
}

/* Webflow work pages set [data-text="step"]{opacity:0} as custom CSS to prevent
   flash on load. The dial persists outside Barba, so that rule sticks after
   navigating back to home. Override it here — the FOUC rule above (line 30)
   keeps step text hidden until .rhp-home-ready is added. */
.dial_component[data-dial-ns="home"] [data-text="step"] {
  opacity: 1;
}

/* While ScrambleText is animating, the random char string has no whitespace
   and cannot wrap on word boundaries. Allow break-anywhere wrapping for the
   duration of the scramble so the text never overflows the dial. The class
   is removed onComplete, restoring normal word-based wrapping. */
[data-text="step"].is-scrambling,
.heading-style-h7.is-step.is-scrambling {
  overflow-wrap: anywhere;
  word-break: break-word;
}

.dial_component[data-dial-ns="home"] .dial_label-wrap {
  text-align: center;
}

/* Mobile: position dial UI 16px below the white dot indicator */
@media (max-width: 991px) {
  .dial_component[data-dial-ns="home"] .dial_layer-ui {
    top: calc(50% + var(--dial-large-height) / 2 * 1.55 + 0.5rem + 16px - 1rem);
  }
}

/* CMS list can be hidden on home */
.dial_component[data-dial-ns="home"] .dial_cms-list {
  display: none;
}

/* ====== Work/case-studies specific ====== */
[data-barba-namespace="work"] .video-cover {
  height: 100%;
  width: 100%;
  object-fit: cover;
}

/* Close link (case-homepage-link) — 1px left offset for alignment */
.dial_component .case-homepage-link {
  left: 1px;
}

/* Work page: first-screen proportions — video fills, title visible above fold (desktop only).
   Applies on initial paint via [data-barba-namespace] — no JS guard needed. */
@media (min-width: 992px) {
  [data-barba-namespace="work"] .section_case-video.is-header {
    min-height: calc(var(--dial-case-height) - var(--dial-case-title-gap));
    display: flex;
    flex-direction: column;
  }
  [data-barba-namespace="work"] .section_case-video .dial_video-wrap,
  [data-barba-namespace="work"] .section_case-video .video-cover,
  [data-barba-namespace="work"] .section_case-video video {
    flex: 1;
    min-height: 0;
    object-fit: cover;
  }

  /* Override aspect-ratio so video in first section can grow vertically */
  [data-barba-namespace="work"] .section_case-video .dial_video-wrap,
  [data-barba-namespace="work"] .section_case-video .video-cover {
    aspect-ratio: auto;
    height: 100%;
  }
}

/* Work page: video fills wrapper completely (100% width and height) */
.dial_component[data-dial-ns="work"] #fg-video-wrap {
  position: relative;
  overflow: hidden;
}
.dial_component[data-dial-ns="work"] #fg-video-wrap .dial_fg-video,
.dial_component[data-dial-ns="work"] #fg-video-wrap .video-cover {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ====== Namespace-based visibility (data-dial-ns on persistent dial) ====== */
/* Work: hide ticks, step text, work-link; show case-homepage-link */
.dial_component[data-dial-ns="work"] .dial_layer-ticks {
  display: none;
}
.dial_component[data-dial-ns="work"] .dial_work-link {
  visibility: hidden;
  pointer-events: none;
}
.dial_component[data-dial-ns="work"] .heading-style-h7.is-step {
  display: none;
}
/* Home: hide case-homepage-link */
.dial_component[data-dial-ns="home"] .case-homepage-link {
  display: none;
}

/* ====== Work page: dial_layer-fg as scrollable container ====== */
.dial_component[data-dial-ns="work"] .dial_layer-fg {
  width: var(--dial-case-width);
  height: var(--dial-case-height);
  border-radius: var(--dial-case-border-radius);
  margin: auto;
  aspect-ratio: auto;
  overflow-x: hidden;
  overflow-y: auto;
  display: flex;
  flex-flow: column;
  align-items: stretch;
  background-color: transparent;
  /* Hide scrollbar at namespace level (no-scrollbar class can be lost during Barba transitions) */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.dial_component[data-dial-ns="work"] .dial_layer-fg::-webkit-scrollbar {
  display: none;
}

/* Work: hide labels — !important overrides IX2 reinit which resets inline opacity */
.dial_component[data-dial-ns="work"] .dial_layer-ui {
  opacity: 0 !important;
  pointer-events: none;
}

/* Hide scrollbar on work view */
.dial_layer-fg.no-scrollbar,
.dial_layer-fg.no-scrollbar .case-studies_wrapper {
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.dial_layer-fg.no-scrollbar::-webkit-scrollbar,
.dial_layer-fg.no-scrollbar .case-studies_wrapper::-webkit-scrollbar {
  display: none;
}

/* Hide scrollbar on about/contact pages (Barba container is scroll wrapper, not <body>) */
[data-barba-namespace="about"],
[data-barba-namespace="contact"] {
  scrollbar-width: none;
  -ms-overflow-style: none;
}
[data-barba-namespace="about"]::-webkit-scrollbar,
[data-barba-namespace="contact"]::-webkit-scrollbar {
  display: none;
}

/* ====== Desktop custom cursor ====== */
.cursor_component {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 9999;
  pointer-events: none;
}

/* Wrapper is always 6rem × 6rem, centred on mouse; dot inside resizes without affecting position */
.cursor_dot-wrapper {
  position: absolute;
  left: 0;
  top: 0;
  width: 6rem;
  height: 6rem;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: translate3d(-9999px, -9999px, 0);
  transform-origin: 50% 50%;
  will-change: transform;
}

.cursor_dot {
  /* Default: dot state - 1rem x 1rem, solid white, 1px border */
  width: 1rem;
  height: 1rem;
  border-radius: 999px;
  background: #fff;
  border: 1px solid #fff;
  display: grid;
  place-items: center;
  will-change: width, height, background-color, border-color;
  transition: width 0.25s ease, height 0.25s ease, background-color 0.25s ease, border-color 0.25s ease;
  position: relative;
}

/* When no wrapper (legacy): dot is positioned directly */
.cursor_component > .cursor_dot {
  position: absolute;
  left: 0;
  top: 0;
  transform: translate3d(-9999px, -9999px, 0);
  transform-origin: 50% 50%;
}

.cursor_label {
  position: absolute;
  font-size: 12px;
  letter-spacing: 0.12em;
  opacity: 0;
  transform: scale(0.9);
  will-change: opacity, transform;
  user-select: none;
  white-space: nowrap;
  transition: opacity 0.25s ease, transform 0.25s ease;
  color: #fff !important;
  -webkit-text-fill-color: #fff !important;
}

.cursor_arrows {
  position: absolute;
  inset: 0;
  opacity: 0;
  will-change: opacity;
  transition: opacity 0.25s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

.cursor_arrows svg {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  transition: color 0.25s ease;
}

/* Cursor state: dot (default) */
[data-cursor="dot"] {
  cursor: none !important;
}

/* Cursor state: solid-orange */
[data-cursor="solid-orange"] {
  cursor: none !important;
}

/* Cursor state: arrow-orange-outline */
[data-cursor="arrow-orange-outline"] {
  cursor: none !important;
}

/* Cursor state: arrow-white-outline */
[data-cursor="arrow-white-outline"] {
  cursor: none !important;
}

/* ====== Contact menu (.section_contact + .contact_overlay) ====== */
.section_contact {
  display: none;
}

.contact_overlay {
  opacity: 0;
}

/* Home intro: step text SplitText line masks */
.home-intro-line {
  overflow: hidden;
}

/* Home intro: initial black background (fallback before JS runs) */
.dial_component[data-dial-ns="home"] .dial_layer-bg {
  background-color: #000;
}

/* ====== Transition dial (static teal ticks for page transitions) ====== */
/* Scale by TICK_RING_EXPAND (~1.184) so tick ring matches homepage dial size; uses dial-large */
.transition-dial {
  display: flex;
  justify-content: center;
  align-items: center;
  width: calc(var(--dial-large-width) * 1.184);
  height: calc(var(--dial-large-height) * 1.184);
  min-width: var(--dial-small-width);
  min-height: var(--dial-small-height);
  pointer-events: none;
}

/* When Flip reparents the dial into the about-page wrapper, shrink to small size.
   Flip reads this CSS end-state and animates width/height from large → small. */
.about_dial-wrapper .transition-dial {
  width: var(--dial-small-width);
  height: var(--dial-small-height);
  min-width: 0;
  min-height: 0;
}

.transition-dial .transition-dial_canvas {
  width: 100%;
  height: 100%;
  display: block;
  transform-origin: 50% 50%;
}

/* ====== About page dial ticks (scaled-down homepage style) ====== */
/* Fix: wrapper has height:0 from Webflow — ensure it contains the dial */
.about_dial-wrapper {
  min-height: 6rem;
  height: auto;
  display: flex;
  justify-content: center;
  align-items: center;
}

.about_dial-wrapper .about_dial-link {
  display: block;
  width: var(--dial-small-width);
  height: var(--dial-small-height);
}

[data-barba-namespace="about"] .about_dial-wrapper .dial_layer-ticks,
[data-barba-namespace="about"] .about_dial-wrapper #dial_ticks-canvas {
  position: relative !important;
  inset: auto !important;
  width: var(--dial-small-width) !important;
  height: var(--dial-small-height) !important;
  min-width: var(--dial-small-width) !important;
  min-height: var(--dial-small-height) !important;
  aspect-ratio: 1 !important;
  pointer-events: none;
  transform-origin: 50% 50%;
}

/* ====== Case Video Progress Bar ====== */
.section_case-video {
  position: relative;
}

.case-video_progress-track {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 1rem;
  z-index: 10;
  cursor: none;
}

.case-video_progress-track::before {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.2);
}

.case-video_progress-hover {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 0;
  background: rgba(255, 255, 255, 0.3);
  pointer-events: none;
}

.case-video_progress-fill {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 0;
  background: #05EFBF;
  pointer-events: none;
}

/* SplitText word wrappers need inline-block for yPercent transform */
.case-title-word {
  display: inline-block;
}

/* Clip mask for word-level entrance animation (yPercent:-100 → 0) */
.section_case-title h1,
.section_case-title h6 {
  overflow: hidden;
}

/* ====== Video Loading Spinner ====== */
.rhp-video-spinner {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 48px;
  height: 48px;
  z-index: 5;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.3s ease;
}
.rhp-video-spinner.is-active {
  opacity: 1;
}

/* Reduced-motion fallback: static ring indicator (no animation) */
.rhp-video-spinner-fallback {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 32px;
  height: 32px;
  border: 3px solid rgba(255,255,255,0.3);
  border-top-color: #fff;
  border-radius: 50%;
  z-index: 5;
  pointer-events: none;
  opacity: 0;
  transition: none;
}
.rhp-video-spinner-fallback.is-active {
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  .rhp-video-spinner {
    transition: none;
  }
}

/* ====== Mobile white dot indicator (sector position at 6 o'clock) ====== */
/* Positioned below the max tick extension: dial radius * ~1.55 accounts for gap + 50%-longer maxLen */
.dial_sector-dot {
  position: absolute;
  bottom: calc(50% - var(--dial-large-height) / 2 * 1.55 - 0.5rem + 1rem);
  left: 50%;
  transform: translateX(-50%);
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #fff;
  z-index: 5;
  pointer-events: none;
  display: none;
}

@media (max-width: 991px) {
  .dial_component[data-dial-ns="home"] .dial_sector-dot {
    display: block;
  }
}

/* Hide dot on non-home pages */
.dial_component[data-dial-ns="work"] .dial_sector-dot,
.dial_component[data-dial-ns="about"] .dial_sector-dot,
.dial_component[data-dial-ns="contact"] .dial_sector-dot {
  display: none !important;
}

/* ====== Mobile: nav fixed transparent overlay ====== */
@media (max-width: 991px) {
  .nav {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1000;
    background: transparent;
  }
}

/* ====== Work page mobile: full-screen content ====== */
@media (max-width: 991px) {
  .dial_component[data-dial-ns="work"] .dial_layer-ui {
    display: none !important; /* !important overrides IX2 which sets display:flex inline */
  }

  /* Full viewport — nav is fixed overlay, no subtraction needed */
  .dial_component[data-dial-ns="work"] {
    height: 100dvh;
  }

  /* fg fills the full component */
  .dial_component[data-dial-ns="work"] .dial_layer-fg {
    width: 100%;
    height: 100%;
    border-radius: 0;
  }

  /* Allow touch scroll on work/case/about pages (home keeps touch-action:none for dial) */
  .dial_component[data-dial-ns="work"],
  .dial_component[data-dial-ns="about"] {
    touch-action: pan-y;
  }

  :root {
    --dial-case-width: 100vw;
    --dial-case-height: 100dvh;
    --dial-case-border-radius: 0;
  }
}

/* Contact section above everything on mobile */
@media (max-width: 991px) {
  .section_contact {
    position: fixed;
    inset: 0;
    z-index: 1001;
    overflow: hidden;
  }
  .nav_contact-pullout {
    min-width: 0 !important;
    max-width: 100vw !important;
    width: 100vw !important;
    box-sizing: border-box;
  }
}

/* Hide "Who We Are" and "Contact" nav links on work pages (mobile) */
@media (max-width: 991px) {
  [data-barba="wrapper"]:has(.dial_component[data-dial-ns="work"]) .nav_about-link,
  [data-barba="wrapper"]:has(.dial_component[data-dial-ns="work"]) .nav_contact-link {
    display: none !important;
  }
}

/* Disable custom cursor on touch devices */
@media (hover: none), (pointer: coarse) {
  .cursor_component {
    display: none !important;
  }
  .dial_component {
    cursor: auto;
  }
  [data-cursor] {
    cursor: auto !important;
  }
}

/* Autoplay fallback — play overlay for no-controls videos */
.rhp-play-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 5;
  pointer-events: auto;
  cursor: pointer;
}

.rhp-play-overlay svg {
  width: 52px;
  height: 51px;
  color: #fff;
  opacity: 0.9;
  transition: opacity 0.2s;
}

.rhp-play-overlay:hover svg,
.rhp-play-overlay:active svg {
  opacity: 1;
}

/* Step text tap-to-play state */
[data-text="step"].is-tap-to-play {
  cursor: pointer;
}

/* ====== Video overlays ====== */

/* Ensure ::after has a positioning context at all times (including during clearProps) */
#fg-video-wrap {
  position: relative;
}

/* FG overlay: 15% black, opacity driven by JS via --fg-overlay-opacity */
#fg-video-wrap::after {
  content: '';
  display: block;
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.15);
  opacity: var(--fg-overlay-opacity, 0);
  z-index: 1;
  pointer-events: none;
}

/* About icon: fill remaining viewport height (about-icon-scale.js sets vars) */
/* Formula: 100svh - top-offset - header - titles */
/* --top-offset measured from .about_r-link offsetTop (padding + line-height strut) */
.section_about-hero .icon-embed-r {
  height: calc(100svh - var(--top-offset, 0px) - var(--header-height, 0px) - var(--titles-height, 0px));
  width: auto;
}
/* FOUC guard: cap height until JS sets --icon-scale-ready */
.section_about-hero:not([style*="--icon-scale-ready"]) .icon-embed-r {
  max-height: 50svh;
}
.section_about-hero .icon-embed-r svg {
  height: 100%;
  width: auto;
}

/* Swiper sliders: max height = viewport minus 4 accordion titles.
   Fade mode uses position:absolute slides, so height lives on the container.
   Images keep natural aspect ratio, capped so they don't blow up on tall screens. */
/* --slide-max-height is the smaller of viewport-minus-titles and image-max-width+caption,
   set by JS after measuring .about_image-wrapper max-width + caption height. */
.section_about-hero [data-slider] {
  height: var(--slide-max-height, calc(100svh - var(--accordion-titles-height, 256px)));
}
.section_about-hero [data-slider] .swiper-slide {
  height: 100%;
}
.section_about-hero [data-slider] .slide-caption {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
}
.section_about-hero [data-slider] .slide-caption .about_image-wrapper {
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.section_about-hero [data-slider] .slide-caption .about_image-wrapper img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}
.section_about-hero [data-slider] .slide-caption .spacer-medium {
  flex-shrink: 0;
}

/* Mobile/tablet: auto height — content determines slider height, no JS cap */
@media (max-width: 991px) {
  .section_about-hero [data-slider] {
    height: auto;
  }
  .section_about-hero [data-slider] .swiper-slide {
    height: auto;
    position: relative;
    width: 100% !important;
    left: 0 !important;
  }
  .section_about-hero [data-slider] .slide-caption {
    height: auto;
  }
}
