/* Styles specific to the /site/ landing page (public/site/index.html) — kept out of
   shared.css since the rest of this file (everything below the header) has no equivalent
   on the other /site/* pages. The glass EFFECT itself (blur + saturate + wavy SVG-
   displacement refraction) is shared with every other /site/* page via shared.css's own
   .site-header — this file's .site-header--glass only overrides the COLOR scheme (white
   text) for this page specifically, because it overlays a dark, busy hero rather than the
   plain light content the other pages' headers blur over, where the default dark-on-light
   palette already reads fine through the blur.

   Two things this page does differently from every other /site/* page:
   1. The header is `position: fixed` here (see .site-header--glass below) rather than the
      shared `position: sticky`, and floats ON TOP of the hero content instead of pushing
      it down from the very first frame — the content shows (softly distorted) through it,
      which is the whole point of the effect. The other pages don't need this: their content
      already starts right below a sticky header in normal flow, and only scrolls under it
      (now translucent) once the page is scrolled — no fixed positioning required there.
   2. The hero itself is a REAL export running inside an iframe, sized one of two ways
      depending on the pair index.html picked (see its own `fluid` flag comment):
        - Fixed-canvas+scale (Blob, and any future non-fluid pair): the iframe runs at a
          fixed, native 1920x1080 resolution and is never resized/reflowed internally —
          instead the iframe element itself is scaled up/down with a CSS transform (set by
          JS in index.html, recomputed on window resize) to always fully COVER the
          viewport below the header, with zero letterbox bars and no scrollbar, ever.
          Scaling the element externally like this does not change the iframe's own
          internal layout viewport, so whatever's running inside (absolutely-positioned
          UI with no self-repositioning of its own) always sees a stable 1920x1080
          "window" exactly like it would running completely standalone.
        - Fluid (Cloud): the iframe is sized to 100%/100% of this stage instead — its
          internal layout viewport genuinely IS the real viewport, no transform involved.
          This is safe here specifically because Cloud's own widgets (Cloud Nav 3D, Cloud
          Text Marquee) each call the sandbox's own getContainerSize() and keep themselves
          matched to whatever that real size actually is (window.myWindow's own
          onUpdate-backed resize/reposition setter) — unlike the earlier, cruder
          width:100%;height:100% attempt this comment used to warn against, which broke
          layout and click targeting because nothing inside was resizing/repositioning
          *itself* to match; the content just silently drifted out of place instead. */

html, body.landing-body {
  height: 100%;
  margin: 0;
  overflow: hidden;
}

body.landing-body {
  position: relative;
  background: #0a0a0a;
}

/* ---- Liquid glass header ---- */

.site-header--glass {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  border-bottom: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(255, 255, 255, 0.10);
  /* The wavy refraction comes from #liquid-glass-distort (an SVG feTurbulence +
     feDisplacementMap filter, defined inline in index.html) chained with blur+saturate —
     the combination that reads as "glass with depth" rather than a flat frosted panel.
     Chaining an SVG filter reference into backdrop-filter works the same as it does for
     the plain filter property. */
  backdrop-filter: url(#liquid-glass-distort) blur(16px) saturate(1.6);
  -webkit-backdrop-filter: blur(16px) saturate(1.6); /* Safari ignores SVG refs in -webkit-backdrop-filter; still gets blur+saturate */
  /* A thin bright line along the top edge + a soft inner glow along the bottom — the two
     details that read as "a pane of glass catching light" rather than just "blurred". */
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    inset 0 -1px 12px rgba(255, 255, 255, 0.06),
    0 8px 30px rgba(0, 0, 0, 0.25);
}

/* Browsers with no backdrop-filter support at all (rare in 2026, but real) get a plain
   translucent dark bar instead of a fully transparent one — still legible, just not glassy. */
@supports not (backdrop-filter: blur(1px)) {
  .site-header--glass {
    background: rgba(10, 10, 10, 0.82);
  }
}

/* Light-on-glass palette -- the shared header's default colors (dark text for a white
   page background) would be close to illegible over this page's own dark hero content
   showing through the glass. */
.site-header--glass .logo-link,
.site-header--glass .logo-text {
  color: #ffffff;
}

.site-header--glass nav a {
  color: rgba(255, 255, 255, 0.78);
}

.site-header--glass nav a:hover {
  background: rgba(255, 255, 255, 0.14);
  color: #ffffff;
}

.site-header--glass nav a.active {
  background: rgba(255, 255, 255, 0.16);
  color: #ffffff;
}

.site-header--glass .cta {
  background: rgba(255, 255, 255, 0.92);
  color: #111;
}

.site-header--glass .cta:hover {
  background: #ffffff;
}

/* Hamburger button + its dropdown -- shared.css's own defaults (dark text on a plain white
   card) were never overridden here, so on every other /site/* page this looks right sitting
   under a plain light header, but on THIS page it opened as a stray white box with dark text,
   completely out of step with the glass/white-on-dark treatment the rest of this header
   already gets. The dropdown reuses the header's own glass recipe (same translucency, blur,
   and edge-light treatment) so it reads as a continuation of the same pane, not a foreign
   control. */
.site-header--glass .nav-more-toggle {
  color: rgba(255, 255, 255, 0.78);
}

.site-header--glass .nav-more-toggle:hover,
.site-header--glass .nav-more-toggle[aria-expanded="true"] {
  background: rgba(255, 255, 255, 0.14);
  color: #ffffff;
}

.site-header--glass .nav-more-menu {
  background: rgba(255, 255, 255, 0.10);
  border-color: rgba(255, 255, 255, 0.14);
  backdrop-filter: url(#liquid-glass-distort) blur(16px) saturate(1.6);
  -webkit-backdrop-filter: blur(16px) saturate(1.6);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    inset 0 -1px 12px rgba(255, 255, 255, 0.06),
    0 8px 30px rgba(0, 0, 0, 0.25);
}

@supports not (backdrop-filter: blur(1px)) {
  .site-header--glass .nav-more-menu {
    background: rgba(10, 10, 10, 0.9);
  }
}

.site-header--glass .nav-more-menu a {
  color: rgba(255, 255, 255, 0.78);
}

.site-header--glass .nav-more-menu a:hover,
.site-header--glass .nav-more-menu a.active {
  background: rgba(255, 255, 255, 0.16);
  color: #ffffff;
}

/* ---- Hero stage ----
   Full-bleed under the fixed glass header (by design — the header overlays it, it doesn't
   push it down). position:fixed + inset:0 means this contributes nothing to document flow
   at all, so there is no content-height calculation left for a scrollbar to ever come from;
   html/body's own overflow:hidden above is just a defensive backstop. */

.landing-stage {
  position: fixed;
  inset: 0;
  overflow: hidden;
  background: #0a0a0a;
}

/* index.html's script owns this element's real width/height and (for a non-fluid pair
   only) its `transform: scale(...)`. For a non-fluid pair (Blob) it sets a fixed px width/
   height (1920x1080 desktop, 390x844 mobile) plus the scale transform to cover the stage
   exactly WITHOUT letting the iframe's own internal viewport drift out of its authored
   design ratio -- that drift is what used to crop/misplace anything not pinned to the
   top-left on those widgets, which have no self-repositioning of their own. For a fluid
   pair (Cloud) it sets plain percentage width/height instead (no transform at all) --
   safe there because that pair's widgets track their own real container size themselves
   (getContainerSize(), see landing.css's own top-of-file comment and index.html's `fluid`
   flag comment). 1920x1080 below is only a pre-JS fallback (default variant is desktop,
   non-fluid sizing) in case the script somehow fails to run. */
#landing-iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 1920px;
  height: 1080px;
  border: 0;
  display: block;
  transform-origin: 0 0;
}

/* A small credit line, shown only as a fixed overlay near the very bottom of the stage —
   intentionally NOT competing for layout space (that's what caused the sizing bug), so it
   can't affect the hero's sizing no matter the viewport shape. */
.landing-footer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 8px;
  /* Above the ad bar's own 500 (shared.css's .ad-bottom-bar) -- this used to sit at z-index
     60, well underneath it, so the Privacy Policy/Terms links added here were rendered but
     visually hidden behind the ad bar for as long as it's shown (its default state, until a
     visitor dismisses it) -- confirmed by the two rules' own numbers, not just a visual
     guess. */
  z-index: 600;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 8px;
  pointer-events: none;
  color: rgba(255, 255, 255, 0.45);
  font-size: 12px;
}

/* Shifts up to clear the ad bar entirely (rather than just out-z-indexing it) once one is
   showing -- body.has-ad-bar is the same toggle shared.css's own padding-bottom rule already
   keys off, kept in sync by each page's own ad-dismiss script. */
body.has-ad-bar .landing-footer { bottom: 106px; }
@media (max-width: 640px) {
  body.has-ad-bar .landing-footer { bottom: 74px; }
}

.landing-footer a {
  color: rgba(255, 255, 255, 0.6);
  text-decoration: none;
  pointer-events: auto;
}

.landing-footer a:hover {
  color: #ffffff;
}
