/* Rexity 3D hero — scoped styles.
   Everything is namespaced under .rx3d-hero. The page this drops into is a large
   Webflow document with its own global rules, so there are deliberately no bare element
   selectors (no `h1`, no `body`) — those would leak into the rest of the site. */

@font-face {
  font-family: RxAnton;
  src: url('/assets/3d-hero/fonts/anton-latin.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: block;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: RxAnton;
  src: url('/assets/3d-hero/fonts/anton-latin-ext.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: block;
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

.rx3d-hero {
  --rx-ground: #ffffff;
  --rx-ink: #7c3aed;
  --rx-accent: #a63a5a;
  --rx-header: 84px;

  position: relative;
  width: 100%;
  min-height: 100svh;
  margin: 0 0 clamp(48px, 6vw, 96px);
  /* The site's `hero` class also sets overflow, and it was winning — so the canvas and
     the cue spilled past the bottom edge into the section below. */
  overflow: hidden !important;
  isolation: isolate;
  /* The section keeps the site's `hero` class (other scripts and Webflow interactions
     query it), and that class paints its own blue. Ours has to win outright. */
  background: var(--rx-ground) !important;
  background-image: none !important;
}

.rx3d-hero * { box-sizing: border-box; }

/* Screen-reader heading. The visible headline is drawn in WebGL. */
.rx3d-hero .rx3d-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.rx3d-hero .rx3d-stage {
  position: absolute;
  inset: var(--rx-header) 0 0;
  z-index: 0;
  --scene-top-extra: 0px;
  --scene-bottom-extra: 0px;
}

.rx3d-hero .rx3d-canvas {
  display: block;
  width: 100%;
  height: calc(100% + var(--scene-bottom-extra));
  pointer-events: auto;
  touch-action: pan-y;
  mask-image: linear-gradient(to bottom, transparent 0, #000 10%, #000 84%, transparent 99%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 10%, #000 84%, transparent 99%);
}
.rx3d-hero .rx3d-canvas--hovering { cursor: pointer; }
.rx3d-hero .rx3d-canvas--dragging { cursor: grabbing; }

/* Character stands in front of the ring. */
.rx3d-hero .rx3d-character {
  position: absolute;
  left: 50%;
  bottom: 4%;
  z-index: 2;
  height: 68%;
  width: auto;
  transform: translateX(-50%);
  pointer-events: none;
  user-select: none;
}

/* Selection label under the wheel. */
.rx3d-hero .rx3d-label {
  position: absolute;
  left: 50%;
  bottom: 8%;
  z-index: 3;
  margin: 0;
  padding: 9px 18px;
  border: 1px solid rgba(20, 20, 40, .14);
  border-radius: 999px;
  background: rgba(255, 255, 255, .86);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 12px 34px rgba(20, 20, 40, .10);
  color: #1b2b4d;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  white-space: nowrap;
  opacity: 0;
  transform: translate(-50%, 10px);
  transition: opacity .28s ease, transform .28s cubic-bezier(.2, .8, .2, 1);
  pointer-events: none;
}
.rx3d-hero .rx3d-label--visible { opacity: 1; transform: translate(-50%, 0); }

/* Explore cue. */
.rx3d-hero .rx3d-explore {
  position: absolute;
  left: 50%;
  bottom: 42px;
  z-index: 5;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: 54px;
  padding: 15px 8px 12px;
  border-radius: 999px;
  background: var(--rx-ink);
  color: #fff;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
  transform: translateX(-50%);
  transition: transform .26s cubic-bezier(.2, .8, .2, 1), background .16s ease;
}
.rx3d-hero .rx3d-explore:hover { transform: translateX(-50%) translateY(-6px); }
.rx3d-hero .rx3d-explore svg { width: 12px; height: 20px; }

@media (max-width: 760px) {
  .rx3d-hero { --rx-header: 66px; }
  .rx3d-hero .rx3d-character { height: 54%; bottom: 12%; }
  .rx3d-hero .rx3d-canvas {
    transform: translateY(-2%);
    mask-image: linear-gradient(to bottom, transparent 0, #000 8%, #000 86%, transparent 99%);
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 8%, #000 86%, transparent 99%);
  }
  .rx3d-hero .rx3d-label { display: none; }
  .rx3d-hero .rx3d-explore { width: 50px; bottom: 26px; }
}

/* Desktop headroom for the headline. resize() feeds --scene-top-extra into
   camera.setViewOffset, widening the view upward; without it the fit routine drags the
   headline down into the cards on shorter/wider windows. */
@media (min-width: 761px) {
  .rx3d-hero .rx3d-stage { --scene-top-extra: 130px; }
}

/* No WebGL: the character and copy still carry the section. */
.rx3d-hero .rx3d-stage--unavailable .rx3d-canvas { display: none; }

@media (prefers-reduced-motion: reduce) {
  .rx3d-hero .rx3d-explore { transition: none; }
}

/* The previous hero injected a kicker and rotating lines via script
   (.rexity-hero-center -> "More than a studio," + four lines). It targets `.hero`,
   which this section still carries, so it keeps writing into the new hero. Hidden here
   rather than unhooked: other scripts and Webflow interactions also query `.hero`, and
   dropping the class risks breaking them. */
.rx3d-hero .rexity-hero-center { display: none !important; }

/* Blue reveal over the character on load.
   A 0.42s beat before it fires: the page settles first, and because the disc holds its
   start frame during the delay (fill both), a small blue dot sits on him and then bursts
   — the dot-then-expand read, rather than the effect appearing already in progress.
   Rebuilt from our own assets: the character webp is used as a CSS mask, so the blue
   only paints inside his silhouette, and a disc scales up underneath it — the same
   read as the dev page's intro, without depending on that page's loader. */
.rx3d-hero .rx3d-reveal {
  position: absolute;
  left: 50%;
  bottom: 4%;
  z-index: 3;
  height: 68%;
  aspect-ratio: 836 / 2048;
  transform: translateX(-50%);
  overflow: hidden;
  pointer-events: none;
  -webkit-mask: url('/assets/3d-hero/character.webp') center / contain no-repeat;
  mask: url('/assets/3d-hero/character.webp') center / contain no-repeat;
  /* Held until .rx3d-go arrives — see the trigger script. Without this the disc's
     start frame would sit on him as a small blue dot for the whole loader. */
  opacity: 0;
}
.rx3d-hero.rx3d-go .rx3d-reveal {
  animation: rx-reveal-fade .5s ease .12s forwards;
}
.rx3d-hero .rx3d-reveal::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 44%;
  width: 12px;
  height: 12px;
  border-radius: 999px;
  background: #2f5fb5;
  transform: translate(-50%, -50%) scale(1);
}
.rx3d-hero.rx3d-go .rx3d-reveal::before {
  animation:
    rx-reveal-grow .26s cubic-bezier(.4, 0, .6, .4) .12s both,
    rx-reveal-glitch .12s steps(1, end) .12s 2 both;
}
@keyframes rx-reveal-grow {
  from { transform: translate(-50%, -50%) scale(1); }
  to   { transform: translate(-50%, -50%) scale(140); }
}
@keyframes rx-reveal-fade {
  0%, 55% { opacity: 1; }
  100%    { opacity: 0; }
}
/* Filter-only glitch: transform is already owned by the grow animation above, and a
   second animation touching it would override the expansion entirely. */
@keyframes rx-reveal-glitch {
  0%, 100% { filter: none; }
  14%      { filter: drop-shadow(4px 0 0 rgba(255,0,72,.55)) drop-shadow(-4px 0 0 rgba(0,238,255,.45)) saturate(1.35); }
  28%      { filter: none; }
  44%      { filter: drop-shadow(-5px 1px 0 rgba(255,0,72,.5)) drop-shadow(5px -1px 0 rgba(0,238,255,.4)) brightness(1.12); }
  60%      { filter: none; }
}
@media (max-width: 760px) {
  .rx3d-hero .rx3d-reveal { height: 54%; bottom: 12%; }
}
@media (prefers-reduced-motion: reduce) {
  .rx3d-hero .rx3d-reveal { display: none; }
}
