/* =========================================================================
   ALIVE — shared interactivity layer (June 12 2026)
   Pairs with /js/indra.js. Transform/opacity/shadow only: no layout work,
   no paint storms, compositor-friendly. ~2KB, cached site-wide.
   ========================================================================= */

/* Fixed geometric substrate mounted by indra.js */
#indraLayer {
  position: fixed; inset: -12vh -12vw; z-index: 0;
  pointer-events: none; will-change: transform;
  mix-blend-mode: soft-light;
}
/* Ecosystem life on the web's circles: smooth state transitions only */
#indraLayer circle { transition: fill-opacity 0.7s ease, opacity 0.7s ease, stroke-opacity 0.7s ease; }
#indraLayer circle.eco-c { fill: currentColor; fill-opacity: 0.16; }
#indraLayer circle.eco-d { fill-opacity: 0; opacity: 0.35; }
#indraLayer svg { width: 100%; height: 100%; }
/* The engine emits stroke via class; pages that mount their own rig define
   this themselves, injected pages get it here. currentColor follows each
   page's own text color, so the web reads on light and dark alike. */
#indraLayer .geo-stroke { stroke: currentColor; }
/* Content always rides above the web */
body > main, body > header, body > footer, body > nav { position: relative; z-index: 1; }

/* Click ripple: a jewel of the net flaring where the page is touched */
.indra-ripple {
  position: fixed; z-index: 2147483000; pointer-events: none;
  width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%;
  border: 1.5px solid currentColor; opacity: 0.5;
  animation: indra-ripple 0.65s cubic-bezier(0.2, 0.6, 0.3, 1) forwards;
}
@keyframes indra-ripple {
  to { transform: scale(11); opacity: 0; }
}

/* Reveal-on-scroll: applied only via JS, so no-JS renders everything */
.iv-pre { opacity: 0; transform: translateY(14px); }
.iv-in {
  opacity: 1; transform: translateY(0);
  transition: opacity 0.55s ease, transform 0.55s cubic-bezier(0.16, 0.8, 0.3, 1);
}

/* Hover and press life on interactive elements, hover devices only */
@media (hover: hover) and (pointer: fine) {
  a, button, .btn, [role="button"], input[type="submit"],
  .card, .pill, .entry, .lecture, .event {
    transition: transform 0.18s ease, box-shadow 0.18s ease, opacity 0.18s ease;
  }
  button:hover, .btn:hover, [role="button"]:hover, input[type="submit"]:hover,
  .card:hover, .pill:hover {
    transform: translateY(-1.5px);
  }
  .card:hover, .lecture:hover, .event:hover {
    box-shadow: 0 4px 18px rgba(0, 0, 0, 0.10);
  }
  button:active, .btn:active, [role="button"]:active, input[type="submit"]:active,
  .pill:active, a:active {
    transform: translateY(0) scale(0.985);
  }
}

/* Keyboard life */
:focus-visible {
  outline: 2px solid currentColor; outline-offset: 3px; border-radius: 3px;
}

/* Print: reveal states must never hide content on paper */
@media print {
  #indraLayer, .indra-ripple { display: none; }
  .iv-pre { opacity: 1 !important; transform: none !important; }
}

/* The kill switch outranks everything above */
@media (prefers-reduced-motion: reduce) {
  #indraLayer { transform: none !important; }
  .indra-ripple { display: none; }
  .iv-pre { opacity: 1; transform: none; }
  .iv-in { transition: none; }
  a, button, .btn, .card, .pill, .entry, .lecture, .event { transition: none; }
}
