/* ===========================================================================
   Site-wide light mode + theme toggle. Loaded on every page.

   Light mode strategy: the site is a dark Framer export with colors spread
   across tokens, inline styles, and presets — so light mode is done with a
   smart inversion (invert + hue-rotate keeps the #0099ff accent blue) applied
   PER top-level branch, never on <html>/<body> (a root filter would turn every
   fixed element — nav, logo, toggle — into a scroll-away element). Filtering a
   fixed element itself is safe; only fixed DESCENDANTS of a filtered ancestor
   break, and the nav container is itself the fixed element. Photos, videos and
   iframes get the same filter re-applied, which cancels out to natural colors.
   White-on-transparent logo art (background-images, inline SVG) stays inverted
   on purpose — it turns black, which is what light mode wants.
   =========================================================================== */

/* ---- hide the nav's LOCAL/ clock (site-wide; attribute selectors because
   Framer class hashes differ per page). The phone button beside it stays. ---- */
[data-framer-name="Time & Toggle Switch"] > [data-framer-name="Text"] { display: none !important; }

/* ---- the theme switch: one morphing sun/moon glyph, fixed top-left beside
   the logo. Dark (default) shows the moon: the mask dot bites the disc into
   a crescent, rays gone, glyph rotated. Light slides the dot away, shrinks
   the disc to a sun core, and fans the rays back in. Spring-feel overshoot
   bezier stands in for the reference spring. In light mode the control
   passes through the site inversion like everything else, so it's designed
   dark-first and flips automatically. */
.ld-theme-toggle {
  position: fixed;
  top: 41px;
  left: 84px;   /* logo is 40px + 32px wide; 12px gap */
  z-index: 10;
  width: 36px;
  height: 36px;
  padding: 6px;
  border: 0;
  background: transparent;
  color: #e6e8ea;
  cursor: pointer;
  transition: transform .35s cubic-bezier(.22, 1, .36, 1), color .25s ease;
}
.ld-theme-toggle:hover, .ld-theme-toggle:focus-visible {
  color: #0099ff;
  outline: none;
}
.ld-tt-svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  transform: rotate(40deg);   /* moon tilt (dark default) */
  transition: transform .5s cubic-bezier(.3, 1.45, .45, 1);
}
:root[data-theme="light"] .ld-tt-svg { transform: rotate(0deg); }
.ld-tt-maskdot {
  cx: 18px;
  cy: 6px;
  transition: cx .5s cubic-bezier(.3, 1.45, .45, 1), cy .5s cubic-bezier(.3, 1.45, .45, 1);
}
:root[data-theme="light"] .ld-tt-maskdot { cx: 25px; cy: 0px; }
.ld-tt-core {
  r: 8px;
  transition: r .5s cubic-bezier(.3, 1.45, .45, 1);
}
:root[data-theme="light"] .ld-tt-core { r: 5px; }
.ld-tt-rays {
  opacity: 0;
  transform: scale(.3);
  transform-box: fill-box;
  transform-origin: center;
  transition: opacity .4s ease, transform .5s cubic-bezier(.3, 1.45, .45, 1);
}
:root[data-theme="light"] .ld-tt-rays { opacity: 1; transform: scale(1); }
.ld-theme-toggle:active .ld-tt-svg { scale: .88; }
/* hidden while scrolling down (same in-and-out as the nav) */
.ld-theme-toggle.is-hidden { transform: translateY(-130px); }
@media (max-width: 809px) {
  .ld-theme-toggle { top: 22px; left: 60px; width: 34px; height: 34px; }
}
@media (prefers-reduced-motion: reduce) {
  .ld-theme-toggle, .ld-tt-svg, .ld-tt-maskdot, .ld-tt-core, .ld-tt-rays { transition: none; }
}

/* ---- light mode ---- */
[data-theme="light"] body { background: #ffffff !important; }

/* Invert each top-level branch: everything directly under <body> except #main
   (covers the injected hero, logo, toggle, and any runtime portals/overlays),
   and each child of the Framer root inside #main (covers page content and the
   fixed nav container — filtered directly, so its fixed position survives). */
[data-theme="light"] body > *:not(#main),
[data-theme="light"] #main [data-framer-root] > * {
  filter: invert(1) hue-rotate(180deg);
}

/* Real media reads naturally: re-apply the filter so it cancels out. */
[data-theme="light"] img,
[data-theme="light"] video,
[data-theme="light"] iframe,
[data-theme="light"] .ld-emoji {
  filter: invert(1) hue-rotate(180deg);
}
.ld-emoji { display: inline-block; }   /* filter needs a box */

/* difference-blended elements (nav clock, menu chip) self-cancel inside the
   inverted branches — blend normally in light mode; inversion handles color. */
[data-theme="light"] .ld-blend-fix { mix-blend-mode: normal !important; }

/* White-background photos need an edge once the page behind them is white. */
[data-theme="light"] .lhero-photo picture { outline: 1px solid rgba(255, 255, 255, .28); }
[data-theme="light"] .lhero-logo { outline: 1px solid rgba(255, 255, 255, .35); }

/* ===========================================================================
   Site-wide cosmos: three parallax layers of drifting star-dust. Every page
   loads this file, so this is the one place the texture lives (the old dot
   grid it replaces also lived here; the hero's own layers were retired in
   hero.css).

   Fixed overlays ABOVE the content — every section background on the site is
   opaque black, so an underlay would never show through. pointer-events:none
   keeps them inert. Each layer is one repeating tile of hand-placed particles
   (radial-gradient stars); the ELEMENT is oversized and translated by exactly
   one tile per loop, so the drift is seamless and endless. All layers drift
   the same direction at different speeds (parallax depth); the two nearer
   layers breathe slightly (twinkle). Alphas are tuned to read on dark
   surfaces and vanish over photos and white panels.
   =========================================================================== */
/* far layer: fine dust — smallest, faintest, most numerous, slowest feel */
body::before {
  content: "";
  position: fixed;
  /* overdraw only where the drift pulls from: top + right, one tile's worth */
  inset: -470px -470px 0 0;
  z-index: 2147483000;
  pointer-events: none;
  background-image:
    radial-gradient(1.2px 1.2px at 25px 35px,   rgba(255, 255, 255, .22), transparent),
    radial-gradient(1.2px 1.2px at 170px 80px,  rgba(255, 255, 255, .16), transparent),
    radial-gradient(1.2px 1.2px at 300px 42px,  rgba(170, 215, 255, .20), transparent),
    radial-gradient(1.2px 1.2px at 410px 120px, rgba(255, 255, 255, .14), transparent),
    radial-gradient(1.2px 1.2px at 95px 160px,  rgba(255, 255, 255, .20), transparent),
    radial-gradient(1.2px 1.2px at 230px 205px, rgba(255, 255, 255, .24), transparent),
    radial-gradient(1.2px 1.2px at 370px 250px, rgba(255, 255, 255, .16), transparent),
    radial-gradient(1.2px 1.2px at 60px 300px,  rgba(170, 215, 255, .18), transparent),
    radial-gradient(1.2px 1.2px at 190px 340px, rgba(255, 255, 255, .14), transparent),
    radial-gradient(1.2px 1.2px at 330px 390px, rgba(255, 255, 255, .22), transparent),
    radial-gradient(1.2px 1.2px at 440px 330px, rgba(255, 255, 255, .16), transparent),
    radial-gradient(1.2px 1.2px at 120px 430px, rgba(255, 255, 255, .20), transparent),
    radial-gradient(1.2px 1.2px at 280px 455px, rgba(255, 255, 255, .14), transparent),
    radial-gradient(1.2px 1.2px at 415px 20px,  rgba(255, 255, 255, .18), transparent),
    radial-gradient(1.2px 1.2px at 350px 150px, rgba(255, 255, 255, .18), transparent),
    radial-gradient(1.2px 1.2px at 20px 220px,  rgba(255, 255, 255, .16), transparent),
    radial-gradient(1.2px 1.2px at 150px 260px, rgba(255, 255, 255, .22), transparent),
    radial-gradient(1.2px 1.2px at 260px 90px,  rgba(255, 255, 255, .14), transparent),
    radial-gradient(1.2px 1.2px at 90px 50px,   rgba(170, 215, 255, .20), transparent),
    radial-gradient(1.2px 1.2px at 400px 410px, rgba(255, 255, 255, .16), transparent);
  background-size: 460px 460px;
  /* pointer parallax (theme.js): rides `translate` because the drift keyframes
     own `transform`. Far layer barely moves. */
  translate: calc(var(--ldpx, 0) * 3px) calc(var(--ldpy, 0) * 3px);
  animation: ld-cosmos-a 180s linear infinite;
}
/* mid layer: small stars, a touch brighter and bluer, gentle twinkle */
body::after {
  content: "";
  position: fixed;
  inset: -630px -630px 0 0;
  z-index: 2147483000;
  pointer-events: none;
  background-image:
    radial-gradient(1.7px 1.7px at 45px 60px,   rgba(255, 255, 255, .34), transparent),
    radial-gradient(1.7px 1.7px at 210px 140px, rgba(255, 255, 255, .26), transparent),
    radial-gradient(1.7px 1.7px at 380px 90px,  rgba(170, 215, 255, .36), transparent),
    radial-gradient(1.7px 1.7px at 540px 200px, rgba(255, 255, 255, .24), transparent),
    radial-gradient(1.7px 1.7px at 130px 290px, rgba(255, 255, 255, .30), transparent),
    radial-gradient(1.7px 1.7px at 330px 350px, rgba(255, 255, 255, .22), transparent),
    radial-gradient(1.7px 1.7px at 500px 420px, rgba(255, 255, 255, .32), transparent),
    radial-gradient(1.7px 1.7px at 80px 480px,  rgba(255, 255, 255, .24), transparent),
    radial-gradient(1.7px 1.7px at 260px 560px, rgba(170, 215, 255, .30), transparent),
    radial-gradient(1.7px 1.7px at 450px 530px, rgba(255, 255, 255, .26), transparent),
    radial-gradient(1.7px 1.7px at 600px 60px,  rgba(255, 255, 255, .28), transparent),
    radial-gradient(1.7px 1.7px at 30px 180px,  rgba(255, 255, 255, .24), transparent),
    radial-gradient(1.7px 1.7px at 300px 240px, rgba(255, 255, 255, .32), transparent),
    radial-gradient(1.7px 1.7px at 170px 420px, rgba(170, 215, 255, .26), transparent),
    radial-gradient(1.7px 1.7px at 560px 320px, rgba(255, 255, 255, .22), transparent);
  background-size: 620px 620px;
  translate: calc(var(--ldpx, 0) * 7px) calc(var(--ldpy, 0) * 7px);
  animation: ld-cosmos-b 230s linear infinite, ld-twinkle 5.5s ease-in-out infinite alternate;
}
/* near layer: a few brighter stars, slow deep twinkle */
html::before {
  content: "";
  position: fixed;
  inset: -910px -910px 0 0;
  z-index: 2147483000;
  pointer-events: none;
  background-image:
    radial-gradient(2.2px 2.2px at 120px 150px, rgba(255, 255, 255, .45), transparent),
    radial-gradient(2.5px 2.5px at 430px 80px,  rgba(170, 215, 255, .38), transparent),
    radial-gradient(2.2px 2.2px at 720px 240px, rgba(255, 255, 255, .42), transparent),
    radial-gradient(2px 2px at 250px 420px,     rgba(255, 255, 255, .32), transparent),
    radial-gradient(2.5px 2.5px at 620px 560px, rgba(255, 255, 255, .45), transparent),
    radial-gradient(2.2px 2.2px at 840px 700px, rgba(255, 255, 255, .34), transparent),
    radial-gradient(2.5px 2.5px at 90px 760px,  rgba(170, 215, 255, .40), transparent),
    radial-gradient(2.2px 2.2px at 320px 260px, rgba(255, 255, 255, .38), transparent),
    radial-gradient(2px 2px at 540px 380px,     rgba(255, 255, 255, .30), transparent),
    radial-gradient(2.5px 2.5px at 780px 480px, rgba(170, 215, 255, .36), transparent);
  background-size: 900px 900px;
  /* near layer tracks the pointer the most — that difference is the depth */
  translate: calc(var(--ldpx, 0) * 12px) calc(var(--ldpy, 0) * 12px);
  animation: ld-cosmos-c 280s linear infinite, ld-twinkle 8s ease-in-out infinite alternate;
}
/* one full tile per loop = seamless; same heading, different speeds = depth */
@keyframes ld-cosmos-a { to { transform: translate3d(-460px, 460px, 0); } }
@keyframes ld-cosmos-b { to { transform: translate3d(-620px, 620px, 0); } }
@keyframes ld-cosmos-c { to { transform: translate3d(-900px, 900px, 0); } }
@keyframes ld-twinkle  { from { opacity: .68; } to { opacity: 1; } }
/* Light mode: the branch inversion filter never reaches these pseudos — give
   them the site's own inversion so the dust reads dark-on-white, softened. */
[data-theme="light"] body::before,
[data-theme="light"] body::after,
[data-theme="light"] html::before {
  filter: invert(1) hue-rotate(180deg);
  opacity: .7;
}
@media (prefers-reduced-motion: reduce) {
  body::before, body::after, html::before { animation: none; }
}
