/* ==========================================================================
   rituals.css — the site's ceremonial layer (Act II)
   Three subsystems, all pure CSS or driven by js/rituals.js:

     1. RITUAL VEIL   — session-once preloader: the sigil draws itself on a
                        void background, blooms gold, then the veil dissolves
                        through an expanding iris. Markup is injected by
                        rituals.js; nothing here renders unless it runs.
     2. VIEW TRANSITIONS — cross-document choreography for full page
                        navigations (@view-transition). Browsers without
                        support simply ignore every rule. Zero JS.
     3. CURSOR HALO   — gold ring + core dot + sparse mote trail, positioned
                        by rituals.js via transform. Fine-pointer only.

   Everything motion-bearing is wrapped in prefers-reduced-motion:
   no-preference (and rituals.js independently refuses to inject under
   reduced motion, so the veil/halo never exist there at all).
   ========================================================================== */

/* ==========================================================================
   1. RITUAL VEIL
   ========================================================================== */

/* Registered so the iris radius can animate inside a mask gradient.
   Browsers without @property fall back to the concurrent opacity fade. */
@property --ritual-iris {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 0%;
}

.ritual-veil {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: var(--void-0, #06040f);
  display: flex;
  align-items: center;
  justify-content: center;
  /* Blocks interaction with the not-yet-revealed page for its ~1.4s life. */
  cursor: wait;
}

.ritual-veil .ritual-sigil {
  width: 120px;
  height: 120px;
  transform: scale(0.94);
  transition:
    transform 0.7s cubic-bezier(0.22, 1, 0.36, 1),
    filter 0.3s ease-out,
    opacity 0.4s ease;
}
.ritual-veil.is-drawing .ritual-sigil { transform: scale(1); }

/* Stroke self-drawing: rituals.js measures each path with getTotalLength(),
   sets dasharray/dashoffset inline, then zeroes the offset — these rules
   only supply the timing. Stagger: outer circle → fire triangle → the W.
   Whole draw completes at ~700ms. */
.ritual-sigil .rs-stroke {
  transition-property: stroke-dashoffset;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
.ritual-sigil .rs-ring { transition-duration: 0.46s; transition-delay: 0s;    }
.ritual-sigil .rs-tri  { transition-duration: 0.40s; transition-delay: 0.14s; }
.ritual-sigil .rs-w    { transition-duration: 0.40s; transition-delay: 0.30s; }

/* The soft wide halo ring blooms only at completion (.is-lit at ~660ms). */
.ritual-sigil .rs-halo {
  opacity: 0;
  transition: opacity 0.3s ease-out;
}
.ritual-veil.is-lit .rs-halo { opacity: 0.16; }
.ritual-veil.is-lit .ritual-sigil {
  filter:
    drop-shadow(0 0 16px rgba(242, 193, 78, 0.8))
    drop-shadow(0 0 48px rgba(242, 193, 78, 0.35));
}

/* Dissolve (.is-dissolving at ~860ms): a transparent circle punched through
   the veil expands from dead centre (soft 12% feathered edge), while a
   back-loaded opacity fade guarantees a clean exit even where animatable
   custom properties in mask gradients are unsupported. Sigil drifts up in
   scale as the light takes it. Veil is removed from the DOM on animationend. */
.ritual-veil.is-dissolving {
  -webkit-mask-image: radial-gradient(circle at 50% 50%,
      transparent calc(var(--ritual-iris) - 12%), #000 var(--ritual-iris));
  mask-image: radial-gradient(circle at 50% 50%,
      transparent calc(var(--ritual-iris) - 12%), #000 var(--ritual-iris));
  animation:
    ritual-iris 0.5s cubic-bezier(0.4, 0, 0.2, 1) forwards,
    ritual-veil-fade 0.5s ease-in forwards;
  pointer-events: none;
  cursor: auto;
}
.ritual-veil.is-dissolving .ritual-sigil {
  transform: scale(1.1);
  opacity: 0;
}

@keyframes ritual-iris {
  from { --ritual-iris: 0%; }
  to   { --ritual-iris: 165%; }
}
@keyframes ritual-veil-fade {
  0%   { opacity: 1; }
  55%  { opacity: 1; }   /* let the iris carry the first half */
  100% { opacity: 0; }
}

/* ==========================================================================
   2. CROSS-DOCUMENT VIEW TRANSITIONS
   --------------------------------------------------------------------------
   Opt every same-origin navigation into a view transition. Old page sinks
   away (fade + settle to 0.99 scale, 240ms), new page rises into place
   (fade up from 10px, 320ms, spring ease). The nav brand carries
   view-transition-name: brand (set inline on .nav-brand in _Layout.cshtml)
   so it glides as a stable element instead of cross-fading with the root.
   Unsupporting browsers ignore all of this; reduced-motion gets none of it.
   ========================================================================== */
@media (prefers-reduced-motion: no-preference) {

  @view-transition {
    navigation: auto;
  }

  ::view-transition-old(root) {
    animation: rituals-page-out 240ms cubic-bezier(0.4, 0, 0.7, 0.4) both;
  }
  ::view-transition-new(root) {
    animation: rituals-page-in 320ms cubic-bezier(0.22, 1, 0.36, 1) both;
  }

  @keyframes rituals-page-out {
    to { opacity: 0; transform: scale(0.99); }
  }
  @keyframes rituals-page-in {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
  }

  /* Smooth positional morph for the persistent nav brand. */
  ::view-transition-group(brand) {
    animation-duration: 320ms;
    animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
  }
  /* The brand is visually identical on both pages — suppress its
     cross-fade so it reads as one continuous object. */
  ::view-transition-old(brand) { animation: none; opacity: 0; }
  ::view-transition-new(brand) { animation: none; opacity: 1; height: 100%; }
}

/* ==========================================================================
   3. CURSOR HALO
   --------------------------------------------------------------------------
   Elements are created by rituals.js only when
   (hover: hover) and (pointer: fine) and motion is allowed; the media wrap
   here is defence in depth. Position comes from JS as
   translate3d(x,y,0) translate(-50%,-50%) — everything else (size, colour,
   state morphs) lives here so it rides the compositor. The native cursor is
   NEVER hidden; the halo is an aura, not a replacement.
   ========================================================================== */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {

  .ritual-cursor {
    position: fixed;
    left: 0;
    top: 0;
    z-index: 9998;
    pointer-events: none;
    mix-blend-mode: screen;   /* glows over dark surfaces */
    opacity: 0;
    transition: opacity 0.3s ease;
    will-change: transform;
  }
  .ritual-cursor.is-on { opacity: 1; }

  /* The ring — 28px at rest, lags the pointer on a ~120ms spring. */
  .ritual-cursor--ring {
    width: 28px;
    height: 28px;
    border: 1.5px solid rgba(242, 193, 78, 0.75);
    border-radius: 999px;
    box-shadow:
      0 0 14px -4px rgba(242, 193, 78, 0.6),
      inset 0 0 8px -5px rgba(242, 193, 78, 0.5);
    transition:
      width 0.28s cubic-bezier(0.22, 1, 0.36, 1),
      height 0.28s cubic-bezier(0.22, 1, 0.36, 1),
      border-color 0.28s ease,
      box-shadow 0.28s ease,
      opacity 0.3s ease;
  }

  /* Crosshair hairlines, revealed only in text mode. */
  .ritual-cursor--ring::before,
  .ritual-cursor--ring::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    background: rgba(242, 193, 78, 0.9);
    opacity: 0;
    transition: opacity 0.2s ease;
  }
  .ritual-cursor--ring::before { width: 16px; height: 1px; transform: translate(-50%, -50%); }
  .ritual-cursor--ring::after  { width: 1px; height: 16px; transform: translate(-50%, -50%); }

  /* Over links / buttons / [data-cursor]: expand to 44px and brighten. */
  .ritual-cursor--ring.is-hot {
    width: 44px;
    height: 44px;
    border-color: var(--gold-hot, #ffdd87);
    box-shadow:
      0 0 26px -4px rgba(255, 221, 135, 0.85),
      inset 0 0 12px -5px rgba(255, 221, 135, 0.6);
  }

  /* Over text inputs: collapse to a crosshair-dot. */
  .ritual-cursor--ring.is-text {
    width: 8px;
    height: 8px;
    border-color: transparent;
    box-shadow: 0 0 10px -2px rgba(242, 193, 78, 0.7);
  }
  .ritual-cursor--ring.is-text::before,
  .ritual-cursor--ring.is-text::after { opacity: 0.9; }

  /* The core dot — 4px, tracks tight on a ~40ms spring. */
  .ritual-cursor--dot {
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--gold-hot, #ffdd87);
    box-shadow: 0 0 8px 1px rgba(242, 193, 78, 0.9);
  }

  /* Trail motes — pooled by JS, animated with WAAPI (600ms fade + drift). */
  .ritual-mote {
    position: fixed;
    left: 0;
    top: 0;
    z-index: 9997;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--gold-hot, #ffdd87);
    box-shadow: 0 0 7px 1px rgba(242, 193, 78, 0.55);
    pointer-events: none;
    mix-blend-mode: screen;
    opacity: 0;
  }
}
