/* ==========================================================================
   URSY FIELD - the estate background. THE FIELD from the URSY.CLOUD /
   URSY.HOSTING design pack, promoted to a global, self-contained estate layer.

   WASHES ONLY, behind a veil, spanning the whole viewport. The source's rule is
   explicit: never orb spheres behind working content. If you can see distinct
   spheres, the implementation is wrong - blur(110px) plus wrapper opacity .45
   is what makes this read as light in the room rather than as graphics.

   Served as a FILE, never inlined: the estate CSP is `style-src 'self'`, so an
   inline style block is dropped by the browser with no visible error.

   LIGHT IS THE DEFAULT. Dark applies only on an explicit [data-theme="dark"],
   never from the visitor's OS preference.
   ========================================================================== */

:root{
  /* wash palette - the AURORA profile from the design pack */
  --o1:oklch(.76 .22 208); --o2:oklch(.66 .30 272);
  --o3:oklch(.86 .21 92);  --o4:oklch(.66 .30 312);
  --ursy-field-bg:#fbfbfa;
  --scrim:rgba(250,250,249,.34);
  --vig:radial-gradient(130% 90% at 50% -22%, rgba(255,255,255,.6), rgba(255,255,255,0) 56%),
        radial-gradient(130% 100% at 50% 120%, rgba(18,20,24,.075), rgba(18,20,24,0) 52%);
}
:root[data-theme="dark"]{
  --o1:oklch(.72 .25 205); --o2:oklch(.62 .33 274);
  --o3:oklch(.82 .24 90);  --o4:oklch(.64 .33 314);
  --ursy-field-bg:#050506;
  --scrim:rgba(5,5,6,.3);
  --vig:radial-gradient(130% 90% at 50% -22%, rgba(255,255,255,.05), rgba(255,255,255,0) 56%),
        radial-gradient(130% 100% at 50% 120%, rgba(0,0,0,.5), rgba(0,0,0,0) 55%);
}

/* The page ground. body goes transparent so the fixed field shows through, and
   isolation:isolate keeps any mix-blend inside the page from reaching it.

   TWO ways in, and they are written as SEPARATE rules on purpose. Several estate
   themes hardcode <html lang="en-GB"> and never call language_attributes(), so
   the marker class the plugin adds through that filter simply never arrives -
   ursy.bot proved it. `html:has(#ursy-field)` keys off the markup instead, which
   is the plugin actually running. They are not combined into one selector list
   because a browser without :has() discards an entire list containing it, which
   would take the working class-based rule down with it. */
html.ursy-field-on{ background:var(--ursy-field-bg); }
html.ursy-field-on body{ background:transparent !important; isolation:isolate; }
html:has(#ursy-field){ background:var(--ursy-field-bg); }
html:has(#ursy-field) body{ background:transparent !important; isolation:isolate; }

#ursy-field{
  position:fixed; inset:0; z-index:-1; overflow:hidden; pointer-events:none;
  contain:strict;               /* four blurred layers - keep them out of the page's paint */
}
#ursy-field .ursy-field__washes{
  position:absolute; inset:-25%;
  filter:blur(110px) saturate(110%); opacity:.45;
  animation:ursyHueCycle 90s linear infinite;
  will-change:filter;
}
#ursy-field .ursy-field__washes i{ position:absolute; display:block; border-radius:50%; will-change:transform; }
#ursy-field .ursy-field__washes i:nth-child(1){ inset-inline-start:-5%; top:-8%; width:64%; height:46%; opacity:.5;
  background:radial-gradient(circle at 45% 40%, var(--o1) 0%, var(--o2) 52%, transparent 74%);
  animation:ursyAurora1 46s ease-in-out infinite; }
#ursy-field .ursy-field__washes i:nth-child(2){ inset-inline-end:-8%; top:12%; width:58%; height:40%; opacity:.4;
  background:radial-gradient(circle at 55% 55%, var(--o2) 0%, var(--o1) 50%, transparent 72%);
  animation:ursyAurora2 54s ease-in-out infinite; }
#ursy-field .ursy-field__washes i:nth-child(3){ inset-inline-start:20%; top:52%; width:60%; height:34%; opacity:.3;
  background:radial-gradient(circle at 50% 50%, var(--o3) 0%, var(--o4) 48%, transparent 74%);
  animation:ursyAurora1 68s ease-in-out infinite reverse; }
#ursy-field .ursy-field__washes i:nth-child(4){ inset-inline-end:2%; bottom:-6%; width:54%; height:30%; opacity:.26;
  background:radial-gradient(circle at 45% 50%, var(--o4) 0%, var(--o2) 52%, transparent 74%);
  animation:ursyAurora2 76s ease-in-out infinite; }
#ursy-field .ursy-field__veil{ position:absolute; inset:0; background:var(--scrim); }
#ursy-field .ursy-field__vig { position:absolute; inset:0; background:var(--vig); }

/* hueCycle restates blur and saturate on every stop: a filter keyframe replaces
   the whole filter list, so naming only hue-rotate would drop the blur mid-cycle
   and the washes would snap into visible spheres. */
@keyframes ursyHueCycle{
  0%  {filter:blur(110px) saturate(110%) hue-rotate(0deg)}
  25% {filter:blur(110px) saturate(130%) hue-rotate(90deg)}
  50% {filter:blur(110px) saturate(110%) hue-rotate(180deg)}
  75% {filter:blur(110px) saturate(130%) hue-rotate(270deg)}
  100%{filter:blur(110px) saturate(110%) hue-rotate(360deg)}
}
@keyframes ursyAurora1{ 0%,100%{transform:translate3d(-14%,-10%,0) scale(1.1) rotate(0deg)} 50%{transform:translate3d(16%,12%,0) scale(1.38) rotate(14deg)} }
@keyframes ursyAurora2{ 0%,100%{transform:translate3d(12%,14%,0) scale(1.28) rotate(0deg)}  50%{transform:translate3d(-16%,-12%,0) scale(1.04) rotate(-16deg)} }

/* Motion is decoration here: stopping it must leave the colour, not a blank page. */
@media (prefers-reduced-motion:reduce){
  #ursy-field .ursy-field__washes,
  #ursy-field .ursy-field__washes i{ animation:none !important; }
}
@media (forced-colors:active){ #ursy-field{ display:none; } }
