/* =========================================================
   VA360 — reference-driven instrument
   Intro → centered lens → circle categories
   Modern · minimal · no page scroll on home
   ========================================================= */

:root {
  --bg: #050908;
  --ink: #0a0a0a;
  --muted: rgba(10, 10, 10, 0.45);
  --hud: #8fd4a8;
  --hud-deep: #5cb87e;
  --hud-soft: rgba(143, 212, 168, 0.35);
  --hud-mint: #a8e6b8;
  --hud-mint-dim: rgba(168, 230, 184, 0.22);
  --lens-size: min(42vmin, 380px);
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --font: "Inter", system-ui, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, monospace;
  --pixel: "Chakra Petch", system-ui, sans-serif;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

:root {
  /* JS bindAppViewportHeight() keeps these honest on mobile chrome */
  --app-vh: 100dvh;
  --app-vw: 100vw;
}

html,
body {
  margin: 0;
  padding: 0;
  width: 100%;
  width: var(--app-vw, 100%);
  height: 100%;
  /* Mobile: fill the visual window (URL bar chrome) — avoid short 100vh gaps */
  height: 100dvh;
  height: var(--app-vh, 100dvh);
  min-height: 100%;
  min-height: 100dvh;
  min-height: var(--app-vh, 100dvh);
  min-height: -webkit-fill-available;
  overflow: hidden;
  overscroll-behavior: none;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
}

body {
  position: fixed;
  inset: 0;
  width: 100%;
  width: var(--app-vw, 100%);
  height: 100%;
  height: 100dvh;
  height: var(--app-vh, 100dvh);
  min-height: -webkit-fill-available;
}

button {
  font: inherit;
  color: inherit;
  cursor: pointer;
  background: none;
  border: 0;
  padding: 0;
}

img {
  display: block;
  max-width: 100%;
}

#app {
  position: relative;
  width: 100%;
  width: var(--app-vw, 100%);
  min-height: 100dvh;
  min-height: var(--app-vh, 100dvh);
  min-height: -webkit-fill-available;
  overflow-y: auto;
  overflow-x: hidden;
  background: #050908;
}

/*
 * Boot curtain — nothing paints (no white, no sky-blue, no stretched poster)
 * until JS marks the intro live or rest frame decoded.
 */
/* .world-bg is deliberately absent from this curtain: it holds the <video>
   whose `poster` is the intro's own first frame. Showing it during boot is
   what replaces the black screen while the video loads (and covers iOS cases
   where autoplay is refused outright, e.g. Low Power Mode). */
.home.is-intro-boot .sky,
.home.is-intro-boot .bg-logo,
.home.is-intro-boot .lens,
.home.is-intro-boot .hud-rings,
.home.is-intro-boot .ghost-field {
  opacity: 0 !important;
  visibility: hidden !important;
  pointer-events: none !important;
}

/* `:not(.is-intro-boot)` added 2026-09-12 — during boot the plate must stay
   visible so the poster frame paints; without this it stayed hidden and the
   poster never showed. */
.home:not(.is-intro-boot):not(.is-intro-live):not(.is-world-rest) .world-bg {
  opacity: 0;
  visibility: hidden;
}

/* ========== INTRO ========== */
/*
 * Vert Dome Globe only — full portrait frame, centered.
 * object-fit: contain keeps the shot intact (letterbox on wide screens).
 * Speed is playbackRate in JS. No CSS filters/transforms on the plate.
 */
.intro {
  position: absolute;
  inset: 0;
  z-index: 50;
  background: #000;
  display: grid;
  place-items: center;
  overflow: hidden;
  pointer-events: none;
  user-select: none;
}

#app.is-booting {
  user-select: none;
}

.intro.is-handoff {
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s linear;
}

.intro.is-done {
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.35s ease;
}

.intro__video {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  object-position: center center;
  background: #000;
  transform: none !important;
  filter: none !important;
  opacity: 1;
  image-rendering: auto;
}

.intro__motion,
.intro__digit {
  display: none !important;
}

/* Intro boot: keep #home in layout (video must size). Layers hide themselves. */

.intro__skip {
  position: absolute;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 80; /* above boot lens */
  font-size: 0.75rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.75);
  background: rgba(10, 12, 16, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 999px;
  padding: 0.55rem 1rem;
  transition: color 0.2s, background 0.2s;
  cursor: pointer;
  pointer-events: auto;
}
.intro__skip:hover {
  color: #fff;
  background: rgba(10, 12, 16, 0.8);
}

/* Ensure [hidden] always wins over layout rules */
[hidden] {
  display: none !important;
}

/*
 * BRIDGE — plain opacity fade of the last clean frame into home.
 * No digital strip, no recolor, no scale punch, no clip-path “effects.”
 */
.bridge {
  position: absolute;
  inset: 0;
  z-index: 55;
  pointer-events: none;
  overflow: hidden;
  background: transparent;
  opacity: 1;
  transition: opacity 0.45s linear;
}

.bridge__digit {
  display: none !important;
}

.bridge__frame {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  opacity: 1;
  transition: opacity 0.45s linear;
}

.bridge__still {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center center;
  background: #000;
  transform: none !important;
  filter: none !important;
  opacity: 1;
  image-rendering: auto;
}

.bridge.is-strip .bridge__frame,
.bridge.is-strip .bridge__still {
  opacity: 0;
  filter: none !important;
  transform: none !important;
}

.bridge.is-fade {
  opacity: 0;
  transition: opacity 0.35s linear;
}

/* ========== HOME ========== */
.home {
  position: relative;
  width: 100%;
  height: 100vh;
  height: var(--app-vh, 100dvh);
  /* Above intro during strip so the hole reveals the real lens, not the video */
  z-index: 40;
  overflow: hidden;
  /* Deep underplate so soft buildings never fall back to blank white */
  background: #050908;
  transition: none;
}

/* World plate window always fills home (no mobile letterbox gap under video) */
.home .world-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Real instrument is already under the hole; reveal as film clears */
.home.is-arriving .lens {
  animation: none;
  opacity: 1;
  --scale: 1;
  filter: drop-shadow(0 14px 28px rgba(0, 0, 0, 0.45));
}

/*
 * Intro: lens hidden (not needed during plate playback).
 * Rest (final frame held): lens fades in, recessed.
 * Hover/nav: lens comes forward — larger, full strength.
 */
.home.is-settle .lens {
  animation: none;
  --scale: 0.82;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  filter:
    drop-shadow(0 10px 22px rgba(0, 0, 0, 0.35))
    brightness(0.88);
  transition:
    transform 0.26s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.28s cubic-bezier(0.22, 1, 0.36, 1),
    filter 0.26s cubic-bezier(0.22, 1, 0.36, 1),
    visibility 0s linear 0.28s;
}

/* After intro final frame: instrument enters — solid against map */
.home.is-settle.is-world-rest .lens {
  opacity: 0.94;
  visibility: visible;
  pointer-events: auto;
  filter:
    drop-shadow(0 12px 28px rgba(0, 0, 0, 0.55))
    brightness(1);
  transition:
    transform 0.26s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.28s cubic-bezier(0.22, 1, 0.36, 1),
    filter 0.26s cubic-bezier(0.22, 1, 0.36, 1),
    visibility 0s;
}

.home.is-settle .lens.is-live {
  animation: none;
}

.home.is-hover .lens,
.home.is-nav .lens {
  --scale: 1.06;
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  filter: drop-shadow(0 16px 32px rgba(0, 0, 0, 0.5)) brightness(1);
  animation: none !important;
}

/* HUD / cats not in intro either */
.home.is-settle:not(.is-world-rest) .hud-rings,
.home.is-settle:not(.is-world-rest) .cats {
  opacity: 0 !important;
  visibility: hidden !important;
  pointer-events: none !important;
}

@media (prefers-reduced-motion: reduce) {
  .bridge__frame,
  .bridge__veil,
  .bridge__still {
    transition-duration: 0.01ms !important;
  }
}

/*
 * Living world layer — dual-buffer drone video under the instrument.
 * Rest: photoreal plate + light veil (logo owns page) — NO video blur.
 * Engaged: clear lock + head-look pan. Travel: brief orb continuum.
 * Filters on <video> are avoided — they force re-raster and look muddy/choppy.
 */
.world {
  --world-wake: 0;
  --wake-ease: cubic-bezier(0.25, 0.8, 0.25, 1);
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  opacity: 0;
  background: #000;
  transition: opacity 0.45s var(--wake-ease);
  transform: none;
  backface-visibility: hidden;
}

.home.is-settle .world,
.home.is-site .world,
.world.is-ready {
  opacity: 1;
}

.world__stage {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  will-change: transform;
  transform: none;
  transform-origin: 50% 50%;
  backface-visibility: hidden;
}

.world__vid {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* Full Vert Dome Globe frame — same as intro, not cover-cropped */
  object-fit: contain;
  object-position: center center;
  opacity: 0;
  transition: opacity 0.38s linear;
  background: #000;
  filter: none !important;
  transform: none !important;
  backface-visibility: hidden;
  image-rendering: auto;
}

.world__vid.is-active {
  opacity: 1;
}

.world[data-aspect="portrait"] .world__vid {
  object-fit: contain;
  object-position: center center;
}

.world__veil {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  /* Light dim only so logo reads — keep plate clarity (not muddy) */
  background:
    radial-gradient(
      ellipse 72% 62% at 50% 48%,
      rgba(6, 8, 12, calc(0.02 + (1 - var(--world-wake)) * 0.08)) 0%,
      rgba(6, 8, 12, calc(0.08 + (1 - var(--world-wake)) * 0.1)) 100%
    );
  transition: opacity 0.4s var(--wake-ease), background 0.4s var(--wake-ease);
  will-change: opacity;
}

.world.is-engaged .world__veil {
  background:
    radial-gradient(
      ellipse 75% 65% at 50% 48%,
      rgba(6, 8, 12, 0) 0%,
      rgba(6, 8, 12, 0.06) 100%
    );
}

/* Travel: slight contrast lift only — still no blur on video */
.world.is-traveling .world__vid.is-active {
  filter: none;
}

.world.is-traveling .world__veil {
  background:
    radial-gradient(
      ellipse 60% 55% at 50% 48%,
      rgba(6, 8, 12, 0.08) 0%,
      rgba(6, 8, 12, 0.28) 100%
    );
}

.home.is-traveling .cats,
.home.is-traveling .ghost-field,
.home.is-traveling .bg-logo {
  opacity: 0 !important;
  pointer-events: none !important;
}

.home.is-traveling .lens {
  --scale: 0.92;
  opacity: 0.75;
  transition:
    transform 0.35s cubic-bezier(0.25, 0.8, 0.25, 1),
    opacity 0.35s ease;
}

/*
 * Vert Dome Globe — fixed viewport WINDOW over the full original plate.
 *
 * .world-bg     = clip frame + sky-blue fill (hides plate rectangle edges)
 * .world-bg__plate = FULL source (1080×1920) sized to cover-equivalent scale,
 *                    sphere center anchored; THIS layer spins as the dial.
 * Video fills the plate 1:1 (no object-fit:cover on a viewport-sized box).
 * Lens/stage stay fixed on top — they are not part of the plate transform.
 */
.world-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  /*
   * MUST match plate sky exactly — any mismatch reads as a hard edge when
   * the full plate rotates / zooms. Sampled from vert-dome-globe final frame
   * top sky + edge blues (blend ≈ #76a7d8).
   */
  background: #76a7d8;
  --plate-w: 100%;
  --plate-h: 100%;
  --plate-l: 0px;
  --plate-t: 0px;
  /* Dial pivot = lens/viewport center in plate-local px (set by layoutWorldPlate) */
  --pivot-x: 50%;
  --pivot-y: 50%;
  /* Dial (JS): rot about pivot; tx/ty stay 0 so circle does not wander */
  --map-tx: 0px;
  --map-ty: 0px;
  --map-rot: 0deg;
  --map-scale: 1;
}

.world-bg__plate {
  position: absolute;
  left: var(--plate-l);
  top: var(--plate-t);
  width: var(--plate-w);
  height: var(--plate-h);
  /*
   * Explicit rotate/scale about --pivot (lens center), not % origin guesswork.
   * Order: move pivot to 0 → scale/rotate → move back. Circle stays fixed on lens.
   */
  transform-origin: 0 0;
  transform:
    translate3d(var(--map-tx), var(--map-ty), 0)
    translate3d(var(--pivot-x), var(--pivot-y), 0)
    rotate(var(--map-rot))
    scale(var(--map-scale))
    translate3d(calc(-1 * var(--pivot-x)), calc(-1 * var(--pivot-y)), 0);
  will-change: transform;
  overflow: hidden;
  background: transparent;
  /* No transition — orientation is fixed from start, never lerps mid-play */
  transition: none;
}

.world-bg__video,
.world-bg__still,
.world-bg__boot-poster {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: fill;
  object-position: center;
  transform: none;
  filter: none !important;
  background: transparent;
  image-rendering: high-quality;
  image-rendering: -webkit-optimize-contrast;
  transition: none;
  pointer-events: none;
}

.world-bg__boot-poster {
  position: absolute;
  inset: 0;
  z-index: 1;
}
.home.is-intro-live .world-bg__boot-poster,
.home.is-world-rest .world-bg__boot-poster,
.home.has-rest-still .world-bg__boot-poster {
  display: none;
}
.home.is-intro-boot .world-bg {
  background: #050908;
}
.home.is-intro-boot .world-bg__video,
.home.is-intro-boot .world-bg__boot-poster {
  opacity: 0 !important;
  visibility: hidden !important;
}
.home.is-intro-live .world-bg__video {
  opacity: 1;
  visibility: visible;
}

.world-bg__still {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
}

/* After populate: 4K still replaces the paused video so zoom/spin stays sharp */
.home.has-rest-still .world-bg__still {
  opacity: 1;
  visibility: visible;
}

.home.has-rest-still .world-bg__video {
  opacity: 0;
  visibility: hidden;
}

.home.is-settle .world-bg,
.home.has-world .world-bg {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .world-bg__plate {
    transform: translateZ(0);
    will-change: auto;
  }
}

/* Fallback still plate under video */
.sky {
  --look-x: 50%;
  --look-y: 50%;
  --look-scale: 1.06;
  --wake-ease: cubic-bezier(0.25, 0.8, 0.25, 1);
  --wake-ms: 0.42s;
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: 0;
  pointer-events: none;
  overflow: hidden;
  transition: opacity 0.4s var(--wake-ease);
}

.home.is-settle:not(.has-world):not(.is-intro-boot) .sky,
.home.is-site:not(.has-world):not(.is-intro-boot) .sky {
  opacity: 1;
}

.home.has-world .sky {
  opacity: 0;
}

.sky__plate {
  position: absolute;
  inset: -12%;
  background-image: url("https://cdn.virtualarchitect360.com/assets/world/buildings-bg.jpg");
  background-repeat: no-repeat;
  background-size: cover;
  background-position: var(--look-x) var(--look-y);
  opacity: 0.92;
  transform: scale(1.02);
  filter: none;
  transform-origin: 50% 50%;
  will-change: transform, opacity, background-position;
  image-rendering: auto;
  transition:
    background-position 0.75s var(--wake-ease),
    opacity var(--wake-ms) var(--wake-ease),
    transform var(--wake-ms) var(--wake-ease);
  animation: none;
}

.home.is-site .sky__plate,
.home.is-hover .sky__plate,
.home.is-nav .sky__plate {
  opacity: 1;
  filter: none;
  transform: scale(1.08);
  animation: none;
}

/* Huge VA logo — fades in during bg slowdown; yields when lens is engaged */
.home {
  --logo-fade: 0; /* 0 during rise → 1 through slowdown → rest */
}

.bg-logo {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-items: center;
  pointer-events: none; /* never blocks lens hit-testing */
  opacity: 0;
  transition:
    opacity 0.35s cubic-bezier(0.25, 0.8, 0.25, 1),
    z-index 0s linear 0.4s;
}

.bg-logo img {
  display: block;
  /* Oversized — bleeds past the viewport edges */
  width: min(190vw, 175vmin);
  height: auto;
  max-width: none;
  object-fit: contain;
  /* dark buildings under: light mark */
  filter: invert(1);
  opacity: 0.12;
  transform: scale(0.96);
  user-select: none;
  transition:
    opacity 0.4s cubic-bezier(0.25, 0.8, 0.25, 1),
    transform 0.45s cubic-bezier(0.25, 0.8, 0.25, 1),
    filter 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
}

/*
 * Settle: logo opacity driven by --logo-fade (synced to video slowdown).
 * No CSS fade-in of its own during intro — JS sets the var each frame.
 */
.home.is-settle .bg-logo {
  opacity: var(--logo-fade, 0);
  z-index: 6;
  transition: none; /* avoid fighting video-synced fade */
}

.home.is-settle .bg-logo img {
  /* Stronger mark during fade-in/out over the plate */
  opacity: 0.82;
  transform: scale(1);
  filter: invert(1) drop-shadow(0 0 56px rgba(255, 255, 255, 0.18));
}

.home.is-settle:not(.is-hover):not(.is-nav) .bg-logo img {
  opacity: 0.85;
}

/* Engaged: logo recedes; lens is forward */
.home.is-hover .bg-logo,
.home.is-nav .bg-logo,
.home.is-site .bg-logo {
  opacity: 0 !important;
  z-index: 1;
  transition:
    opacity 0.35s cubic-bezier(0.25, 0.8, 0.25, 1),
    z-index 0s linear 0.35s;
}

.home.is-hover .bg-logo img,
.home.is-nav .bg-logo img,
.home.is-site .bg-logo img {
  opacity: 0;
  transform: scale(1.06);
}

/*
 * Ghost field — ref: fast spin with nav list
 * Huge pixel word stacked many times, populates with a digital cascade.
 */
.ghost-field {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  pointer-events: none;
  overflow: hidden;
  opacity: 0;
  transition: opacity 0.28s ease;
  user-select: none;
}

.home.is-nav .ghost-field.is-on {
  opacity: 1;
}

.ghost-field__stack {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0;
  width: 100%;
  max-height: 100%;
  transform: translateY(-2%);
}

.ghost-field__row {
  font-family: var(--pixel);
  font-weight: 700;
  /* Much larger than before — fills the field behind the lens */
  font-size: clamp(3.2rem, 15vw, 10.5rem);
  line-height: 0.9;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--hud-mint-dim);
  text-shadow: 0 0 24px rgba(168, 230, 184, 0.12);
  -webkit-font-smoothing: antialiased;
  opacity: 0;
  transform: translateY(0.35em) scale(0.96);
}

.home.is-nav .ghost-field.is-on .ghost-field__row {
  animation: ghost-populate 0.55s cubic-bezier(0.2, 0.85, 0.25, 1) forwards;
  animation-delay: calc(var(--i, 0) * 0.045s);
}

@keyframes ghost-populate {
  0% {
    opacity: 0;
    transform: translateY(0.4em) scale(0.94);
    filter: blur(2px);
    letter-spacing: 0.2em;
  }
  55% {
    opacity: 0.85;
    filter: blur(0);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
    filter: blur(0);
    letter-spacing: 0.04em;
  }
}

/* Subtle digital flicker on the stack after populate */
.home.is-nav .ghost-field.is-on .ghost-field__stack {
  animation: ghost-flicker 2.8s steps(2, end) infinite;
  animation-delay: 0.55s;
}

@keyframes ghost-flicker {
  0%,
  92%,
  100% { opacity: 1; }
  93% { opacity: 0.72; }
  94% { opacity: 1; }
  97% { opacity: 0.85; }
}

/* HUD concentric rings (ref mint green tech rings) */
.hud-rings {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 3;
  width: min(92vmin, 820px);
  height: min(92vmin, 820px);
  transform: translate(-50%, -50%) scale(0.86);
  pointer-events: none;
  opacity: 0;
  transition:
    opacity 0.35s ease,
    transform 0.45s cubic-bezier(0.25, 0.8, 0.25, 1);
}

.home.is-nav .hud-rings {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

.hud-rings__svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}

.hud-rings__c {
  fill: none;
  stroke: var(--hud-mint);
  stroke-opacity: 0.35;
  stroke-width: 0.55;
  vector-effect: non-scaling-stroke;
}

.hud-rings__c--a {
  stroke-opacity: 0.2;
  stroke-dasharray: 1.2 2.4;
}
.hud-rings__c--b {
  stroke-opacity: 0.28;
  stroke-dasharray: 0.8 1.6 3 1.6;
  animation: hud-spin 28s linear infinite;
  transform-origin: 100px 100px;
}
.hud-rings__c--c {
  stroke-opacity: 0.4;
  stroke-width: 0.7;
  stroke-dasharray: 2 3 0.5 3;
}
.hud-rings__c--d {
  stroke-opacity: 0.22;
  stroke-dasharray: 4 5;
  animation: hud-spin 40s linear infinite reverse;
  transform-origin: 100px 100px;
}
.hud-rings__c--e {
  stroke-opacity: 0.18;
  stroke-width: 0.45;
  stroke-dasharray: 0.6 2.2;
}

@keyframes hud-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .ghost-field__row,
  .ghost-field__stack,
  .hud-rings__c--b,
  .hud-rings__c--d {
    animation: none !important;
  }
  .home.is-nav .ghost-field.is-on .ghost-field__row {
    opacity: 1;
    transform: none;
  }
}

/* Centered stage — lens always dead-center of viewport */
.stage {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: grid;
  place-items: center;
  /* room for left nav without shifting lens */
  pointer-events: none;
}

/* ========== LENS ========== */
.lens {
  --spin: 0deg;
  --spin-ccw: 0deg;
  --scale: 1;
  position: relative;
  /* Nothing from the geo-menu layer (lines, marks, building highlights,
     callout boxes) should ever paint in front of the lens — it stays the
     top-most element (DXVXNX, 2026-08-08). */
  z-index: 50;
  width: var(--lens-size);
  height: var(--lens-size);
  aspect-ratio: 1 / 1;
  /* no border-radius clip — gear teeth must not be shaved */
  border-radius: 0;
  pointer-events: auto;
  outline: none;
  background: transparent;
  animation: none;
  transform: scale(var(--scale));
  transition:
    transform 0.4s cubic-bezier(0.25, 0.8, 0.25, 1),
    opacity 0.4s cubic-bezier(0.25, 0.8, 0.25, 1),
    filter 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
  will-change: transform, opacity, filter;
  filter: drop-shadow(0 12px 24px rgba(0, 0, 0, 0.4));
}

/* Click bulge: a bit more while engaged */
.home.is-bulge .lens {
  --scale: 1.1;
  animation: none !important;
  transition: transform 0.28s cubic-bezier(0.33, 1, 0.68, 1);
}

/*
 * Layers from original reference still only (no recolor).
 *  1) core  — glass + VA logo (stationary)
 *  2) marks — classification lettering ring (spins)
 *  3) outer — ridged gear (spins opposite)
 */
.lens__core,
.lens__marks,
.lens__outer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
  background: transparent;
  border-radius: 0;
}

.lens__core {
  z-index: 1;
  transform: none !important;
}

.lens__marks {
  z-index: 2;
  transform: rotate(var(--spin-ccw));
  will-change: transform;
}

.lens__outer {
  z-index: 3;
  transform: rotate(var(--spin));
  will-change: transform;
}

.lens__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  user-select: none;
  pointer-events: none;
  background: transparent;
  border: 0;
  border-radius: 0;
  image-rendering: auto;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  opacity: 1;
  filter: none !important;
  mix-blend-mode: normal;
}

.lens__img--glass {
  position: absolute;
  inset: 0;
  transform: none !important;
}

.lens:focus-visible {
  filter: drop-shadow(0 14px 28px rgba(0, 0, 0, 0.45)) drop-shadow(0 0 0 2px rgba(143, 212, 168, 0.55));
}

/* Engaged site look stays deep (buildings plate is full strength) */
.home.is-site {
  background: #0a0c10;
}

/* ========== CATEGORY LIST (refs 6–10 — pixel HUD labels) ========== */
.cats {
  position: absolute;
  left: max(0.75rem, calc(50% - var(--lens-size) * 1.45));
  top: 50%;
  transform: translateY(-50%);
  z-index: 6;
  display: flex;
  flex-direction: column;
  gap: 1.05rem;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s;
}

.home.is-nav .cats {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.cats__item {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  min-height: 1.85rem;
  padding: 0.35rem 0.85rem 0.35rem 1rem;
  text-align: left;
  opacity: 0;
  transform: translateX(-10px);
  transition:
    opacity 0.28s ease,
    transform 0.32s cubic-bezier(0.2, 0.85, 0.25, 1),
    color 0.2s;
}

.home.is-nav .cats__item {
  opacity: 0.42;
  transform: translateX(0);
  transition-delay: calc(var(--cat-i, 0) * 0.05s + 0.08s);
}

.cats__item:hover {
  opacity: 0.85;
}

.cats__item.is-active {
  opacity: 1;
  transform: translateX(2px);
}

.cats__label {
  position: relative;
  z-index: 1;
  font-family: var(--pixel);
  font-size: clamp(0.62rem, 1.25vw, 0.78rem);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: lowercase;
  color: rgba(230, 245, 235, 0.72);
  -webkit-font-smoothing: antialiased;
  line-height: 1.4;
}

.cats__item.is-active .cats__label {
  color: #0a120e;
}

/* Geometric HUD blade — active only (ref diamond frame) */
.cats__blade {
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 2rem;
  transform: translateY(-50%) scaleX(0.85);
  transform-origin: left center;
  z-index: 0;
  opacity: 0;
  pointer-events: none;
  background: linear-gradient(
    90deg,
    rgba(168, 230, 184, 0.25) 0%,
    rgba(200, 245, 215, 0.92) 38%,
    rgba(168, 230, 184, 0.35) 100%
  );
  border: 1.5px solid rgba(120, 200, 150, 0.85);
  clip-path: polygon(
    0% 50%,
    7% 0%,
    93% 0%,
    100% 50%,
    93% 100%,
    7% 100%
  );
  box-shadow:
    0 0 18px rgba(143, 212, 168, 0.35),
    inset 0 0 12px rgba(255, 255, 255, 0.25);
  transition:
    opacity 0.22s ease,
    transform 0.28s cubic-bezier(0.2, 0.9, 0.25, 1);
}

.cats__item.is-active .cats__blade {
  opacity: 1;
  transform: translateY(-50%) scaleX(1);
}

/* Stagger index for nav items */
.cats__item:nth-child(1) { --cat-i: 0; }
.cats__item:nth-child(2) { --cat-i: 1; }
.cats__item:nth-child(3) { --cat-i: 2; }
.cats__item:nth-child(4) { --cat-i: 3; }

/* ========== FLASH ========== */
.flash {
  position: fixed;
  inset: 0;
  z-index: 100;
  pointer-events: none;
  background: radial-gradient(circle at 50% 50%, #fff 0%, rgba(255, 255, 255, 0.85) 30%, transparent 70%);
  opacity: 0;
}
.flash.is-on {
  animation: flash-burst 0.42s var(--ease) forwards;
}
@keyframes flash-burst {
  0% { opacity: 0; }
  18% { opacity: 1; }
  100% { opacity: 0; }
}

/* ========== CONTENT ========== */
.content {
  position: absolute;
  inset: 0;
  z-index: 20;
  overflow: auto;
  overscroll-behavior: contain;
  background: #0b0b0c;
  color: #eaeaea;
  cursor: default;
}

.content__back {
  position: fixed;
  top: 1.1rem;
  left: 1.1rem;
  z-index: 30;
  opacity: 0.75;
  transition: opacity 0.2s;
  /* logo is dark ink; invert for dark content stage */
  filter: invert(1);
  background: transparent;
}
.content__back:hover {
  opacity: 1;
}
.content__back img {
  width: 72px;
  height: auto;
  object-fit: contain;
  background: transparent;
}

.content__panel {
  max-width: 920px;
  margin: 0 auto;
  padding: 5rem 1.5rem 3rem;
}

.content__eyebrow {
  margin: 0 0 0.75rem;
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: lowercase;
  color: var(--hud);
}

.content__title {
  margin: 0 0 1rem;
  font-weight: 300;
  font-size: clamp(1.8rem, 4vw, 2.6rem);
  letter-spacing: -0.02em;
}

.content__prose {
  max-width: 36rem;
  font-size: 1.02rem;
  line-height: 1.65;
  color: rgba(230, 240, 235, 0.88);
}

.content__prose p {
  margin: 0 0 1rem;
}

.content__contact-line {
  font-family: var(--mono);
  font-size: 0.95rem;
  letter-spacing: 0.04em;
}

.content__contact-line a {
  color: var(--hud-mint, #a8e6b8);
  text-decoration: none;
}

.content__contact-line a:hover {
  text-decoration: underline;
}

.content__muted {
  font-size: 0.88rem;
  color: rgba(200, 220, 210, 0.55);
}

.content__lede {
  margin: 0 0 2rem;
  max-width: 42ch;
  color: rgba(234, 234, 234, 0.65);
  font-weight: 300;
  line-height: 1.55;
}

.content__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0.85rem;
}

.content__card {
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.03);
  cursor: pointer;
  transition: border-color 0.2s, transform 0.25s var(--ease);
}
.content__card:hover {
  border-color: rgba(143, 212, 168, 0.45);
  transform: translateY(-2px);
}
.content__card img {
  width: 100%;
  aspect-ratio: 4/3;
  object-fit: cover;
}
.content__card h3 {
  margin: 0;
  padding: 0.75rem 0.9rem 1rem;
  font-size: 0.9rem;
  font-weight: 500;
}

/* ========== STRUCTURED INTAKE (Packet 03) ========== */
.intake {
  max-width: 36rem;
  margin-top: 2rem;
  padding-top: 1.75rem;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.intake__intents {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.intake__intent-btn {
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  padding: 0.4rem 0.85rem;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 999px;
  background: transparent;
  color: rgba(230, 240, 235, 0.75);
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s, background 0.2s;
}
.intake__intent-btn:hover {
  border-color: var(--hud-soft);
  color: var(--hud-mint);
}
.intake__intent-btn.is-active {
  border-color: var(--hud-deep);
  background: var(--hud-mint-dim);
  color: var(--hud-mint);
}

.intake__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.85rem;
}

.intake label {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-size: 0.82rem;
  color: rgba(200, 220, 210, 0.7);
}

.intake label em {
  font-style: normal;
  color: rgba(200, 220, 210, 0.4);
}

.intake input,
.intake select,
.intake textarea {
  font: inherit;
  font-size: 0.95rem;
  color: rgba(234, 234, 234, 0.92);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 6px;
  padding: 0.55rem 0.65rem;
}

.intake input:focus,
.intake select:focus,
.intake textarea:focus {
  outline: none;
  border-color: var(--hud-soft);
}

.intake__full {
  grid-column: 1 / -1;
}

.intake__hint {
  margin: -0.4rem 0 0;
  font-size: 0.78rem;
  color: rgba(200, 220, 210, 0.5);
}

.intake__hp {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.intake__actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.4rem;
}

.intake__actions .submit-text {
  font-family: var(--mono);
  font-size: 0.85rem;
  letter-spacing: 0.04em;
  padding: 0.55rem 1.1rem;
  border-radius: 6px;
  border: 1px solid var(--hud-deep);
  background: var(--hud-mint-dim);
  color: var(--hud-mint);
  cursor: pointer;
  transition: opacity 0.2s;
}
.intake__actions .submit-text:disabled {
  opacity: 0.6;
  cursor: default;
}

.intake__note {
  margin: 0;
  font-size: 0.75rem;
  color: rgba(200, 220, 210, 0.45);
}

.intake__status {
  margin: 0;
  font-size: 0.85rem;
  padding: 0.5rem 0.7rem;
  border-radius: 6px;
}
.intake__status.is-ok {
  color: var(--hud-mint);
  background: var(--hud-mint-dim);
}
.intake__status.is-error {
  color: #f2b4b4;
  background: rgba(242, 180, 180, 0.12);
}

/* ========== MOBILE PERFORMANCE ========== */
/* Lite path: html.va-lite set by mobile-perf.js (narrow / coarse / 3g / save-data) */
html.va-lite .geo-title,
html.va-lite .geo-aux,
html.va-lite .geo-status,
html.va-lite .cats__item,
html.va-lite .content__back {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

html.va-lite .geo-title {
  background: rgba(4, 12, 10, 0.82);
}

/* Lite: skip heavy cascade/flicker, but keep lettering VISIBLE full-screen */
html.va-lite .letter-field.is-on .letter-field__row,
html.va-lite .home.is-nav .letter-field.is-on .letter-field__stack {
  animation: none !important;
}

html.va-lite .home.is-nav .letter-field.is-on .letter-field__row {
  opacity: 1 !important;
  transform: none !important;
  filter: none !important;
}

html.va-lite .world-bg__plate {
  will-change: auto;
}

html.va-lite .home.is-nav .world-bg__plate,
html.va-lite .home.is-hover .world-bg__plate {
  will-change: transform;
}

html.va-lite .hud-rings__c {
  animation: none !important;
}

/* Reduce paint thrash on continuous filters */
html.va-lite .world-bg__video {
  filter: none !important;
}

/* ========== RESPONSIVE / MOBILE ========== */
/* Touch-friendly defaults (coarse pointers) */
@media (pointer: coarse) {
  .lens {
    /* Slightly larger hit target without changing visual size */
    touch-action: none;
  }

  .intro__skip,
  .content__back,
  .cats__item {
    min-height: 44px;
    min-width: 44px;
  }

  .cats__item {
    padding: 0.5rem 0.95rem 0.5rem 1.05rem;
  }
}

@media (max-width: 720px) {
  :root {
    /* Smaller dial so GEOINT labels + paths have room on phones */
    --lens-size: min(52vmin, 260px);
  }

  /*
   * Phones get a 1536px source instead of the 4096px master. Same image,
   * same framing — only the pixel count changes, and the plate is a soft
   * 0.92-opacity backdrop so the difference isn't visible at phone size.
   *
   * Why this exists: the 4096x4096 master decodes to ~67 MB of RAM. Measured
   * 2026-09-11 in real WebKit (Safari engine, iPhone emulation), the home page
   * decoded ~109 MB of images at once, which kills iOS Safari's content
   * process — the page dies and the visitor sees a permanent black screen.
   * That is the actual, reproduced cause of the long-running
   * "intro video black on mobile" report, not a video/delivery problem.
   * Desktop keeps the full-resolution master.
   */
  .sky__plate {
    background-image: url("https://cdn.virtualarchitect360.com/assets/world/buildings-bg-m.jpg");
  }

  html,
  body,
  #app {
    /* iOS Safari address bar: prefer dynamic viewport */
    height: 100%;
    height: 100dvh;
  }

  #app {
    width: 100%;
    max-width: 100vw;
  }

  .cats {
    left: 50%;
    top: auto;
    bottom: max(1.1rem, env(safe-area-inset-bottom, 0px));
    transform: translateX(-50%);
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.45rem 0.65rem;
    width: min(94vw, 380px);
    padding-left: env(safe-area-inset-left, 0px);
    padding-right: env(safe-area-inset-right, 0px);
  }

  .cats__item {
    min-height: 2.5rem;
    padding: 0.45rem 0.75rem;
  }

  .cats__blade {
    display: none !important;
  }

  .cats__item.is-active .cats__label {
    color: var(--hud-deep);
  }

  .cats__label {
    font-size: clamp(0.68rem, 3.2vw, 0.8rem);
  }

  .ghost-field__row {
    font-size: clamp(1.75rem, 11vw, 4.5rem);
  }

  .hud-rings {
    width: min(96vmin, 520px);
    height: min(96vmin, 520px);
  }

  .intro__skip {
    right: max(0.75rem, env(safe-area-inset-right, 0px));
    bottom: max(0.75rem, env(safe-area-inset-bottom, 0px));
    padding: 0.65rem 1.05rem;
    font-size: 0.72rem;
    min-height: 44px;
  }

  .content {
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
  }

  .content__back {
    top: max(0.85rem, env(safe-area-inset-top, 0px));
    left: max(0.75rem, env(safe-area-inset-left, 0px));
  }

  .content__back img {
    width: 56px;
  }

  .content__panel {
    max-width: 100%;
    padding:
      max(4.25rem, calc(env(safe-area-inset-top, 0px) + 3.5rem))
      max(1rem, env(safe-area-inset-right, 0px))
      max(2.5rem, env(safe-area-inset-bottom, 0px))
      max(1rem, env(safe-area-inset-left, 0px));
  }

  .content__title {
    font-size: clamp(1.55rem, 7vw, 2.1rem);
  }

  .content__prose {
    max-width: none;
    font-size: 0.98rem;
    line-height: 1.6;
  }

  .content__lede {
    max-width: none;
  }

  .content__grid {
    grid-template-columns: 1fr 1fr;
    gap: 0.7rem;
  }

  .content__card h3 {
    font-size: 0.82rem;
    padding: 0.65rem 0.7rem 0.85rem;
  }

  .intake__row {
    grid-template-columns: 1fr;
  }

  .intake__intent-btn {
    padding: 0.5rem 0.85rem;
  }

  /*
   * Intro / settle watermark logo — desktop is intentionally oversized (bleeds).
   * On mobile, scale so the full wordmark fits the screen width with side margin.
   * Fade / JS --logo-fade / engage-hide behavior unchanged.
   */
  .bg-logo img {
    width: min(88vw, 100vmin);
    max-width: 88vw;
  }

  .home.is-settle .bg-logo img {
    /* Same settle look, just smaller — no redesign */
    transform: scale(1);
  }
}

@media (max-width: 480px) {
  :root {
    --lens-size: min(48vmin, 220px);
  }

  .content__grid {
    grid-template-columns: 1fr;
  }

  .cats {
    width: min(96vw, 340px);
    gap: 0.35rem 0.5rem;
  }

  .cats__item {
    min-height: 2.35rem;
    padding: 0.4rem 0.6rem;
  }

  .bg-logo img {
    width: min(84vw, 92vmin);
    max-width: 84vw;
  }
}

/* Landscape phones — keep dial usable, chrome out of the way */
@media (max-height: 420px) and (orientation: landscape) {
  :root {
    --lens-size: min(48vmin, 180px);
  }

  .cats {
    bottom: max(0.5rem, env(safe-area-inset-bottom, 0px));
    width: min(70vw, 420px);
  }

  .intro__skip {
    bottom: max(0.4rem, env(safe-area-inset-bottom, 0px));
    right: max(0.5rem, env(safe-area-inset-right, 0px));
    padding: 0.4rem 0.75rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .lens {
    animation: none !important;
  }
  .sky__plate {
    transition: opacity 0.2s ease, filter 0.2s ease, transform 0.2s ease;
    animation: none !important;
  }
  .flash.is-on {
    animation: none;
    opacity: 0;
  }
}
