/**
 * jalsa-ambience.css — the visual warmth + motion layer for the Jalsa Events static site.
 * ------------------------------------------------------------------------------------
 * A buildless, additive sheet in the house style of `jalsa-events-stage.css` /
 * `jalsa-events-nav-glass.css` / `jalsa-gallery-rebuild.css`. It is loaded LAST so its
 * low-specificity rules win by source order without needing `!important` (except where
 * the reduced-motion / mobile kill-switches must beat a running animation).
 *
 * ## What this file may NOT do (the invariants that matter)
 *
 * There are verification harnesses that compare rendered `document.body.innerText`
 * byte-for-byte against a frozen baseline (`dev/.phase0-innertext.mjs`,
 * `dev/verify-served.mjs`). Therefore, by contract:
 *
 *   1. No rule here may add a text node. Every decorative surface is an empty element or a
 *      canvas created by `jalsa-motion.js`; this sheet only *styles* those generated
 *      classes (`.jalsa-ambience`, `.jalsa-petals`) and adds purely visual properties.
 *   2. Nothing here changes box geometry — no width/height/padding/margin/border-width.
 *      Motion is expressed through `transform`, `opacity`, `filter`, `background-position`
 *      and `border-color` only, all of which are paint-time and cannot move text.
 *   3. The content renderer (`jalsa-content.js`) owns the custom properties `--hero`,
 *      `--img`, `--detail`, `--side`, `--hero-image`, `--feature-image`. This file never
 *      declares, reads, overrides or animates them. The Ken Burns effect animates the
 *      `background-position` of the element that *consumes* `var(--hero)`; it leaves the
 *      variable itself untouched, so the CMS layer keeps full control of the image URL.
 *   4. Every decorative layer is `pointer-events: none`, so navigation, ticket selection
 *      and forms are never intercepted.
 *
 * `prefers-reduced-motion: reduce` disables every animation here, and a companion mobile
 * gate (narrow viewport / coarse pointer) drops the continuous hero drift, because a
 * repainting full-bleed hero plus falling particles is the classic mobile jank source.
 * `jalsa-motion.js` applies the same two conditions before it draws a single petal.
 */

/* ------------------------------------------------------------------ warm palette --
 * Additive, namespaced custom properties. They deliberately do NOT touch the existing
 * `--accent`, `--gold-deep`, `--border`, … tokens: the whole warmth pass is tunable from
 * this one block, and re-pointing `--jalsa-*` at the client's own swatches later is a
 * single-file change.
 */
:root {
  --jalsa-champagne: #f3dcab;
  --jalsa-gold: #c9a24a;
  --jalsa-burgundy: #6d2233;
  --jalsa-rose: #e7b7c0;
  --jalsa-hairline: rgba(201, 162, 74, 0.32);
  --jalsa-veil-top: rgba(255, 240, 205, 0.10);
  --jalsa-veil-bottom: rgba(109, 34, 51, 0.07);
  --jalsa-reveal-distance: 16px;
  --jalsa-reveal-duration: 0.6s;
}

/* ------------------------------------------------------- decorative overlays ----
 * Both elements are created and appended to <body> by `jalsa-motion.js` as SIBLINGS —
 * never as wrappers around authored content, which would risk detaching a `data-od-id`
 * binding. They carry no children and no text.
 */

/* Soft warm vignette: a faint champagne halo at the crown and a burgundy shade at the
 * foot. Fixed, so it cannot affect layout, and pointer-events:none so it cannot trap a
 * click. Blend mode `soft-light` keeps it a tint rather than a wash over the copy. */
.jalsa-ambience {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(120% 78% at 50% -8%, var(--jalsa-veil-top), rgba(255, 240, 205, 0) 56%),
    radial-gradient(120% 88% at 50% 118%, var(--jalsa-veil-bottom), rgba(109, 34, 51, 0) 62%);
  mix-blend-mode: soft-light;
}

/* The petals canvas. `inset:0` + fixed keeps it viewport-anchored; the width/height are
 * restored to device pixels by the script. Zero text nodes by construction. */
.jalsa-petals {
  position: fixed;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* ----------------------------------------------------------- scroll reveal ----
 * `jalsa-motion.js` adds `.jalsa-reveal` (the pre-visible state) and then
 * `.jalsa-reveal-in` once the element scrolls into view. Both classes are applied to
 * AUTHORED elements, which is safe: a class addition cannot detach a `data-od-id`
 * binding, and opacity/transform do not move a character, so `innerText` is unchanged.
 *
 * A fail-safe in the script force-adds `.jalsa-reveal-in` to every target after a short
 * timeout, so a missing IntersectionObserver can never strand content invisible.
 */
.jalsa-reveal {
  opacity: 0;
  transform: translate3d(0, var(--jalsa-reveal-distance), 0);
  transition:
    opacity var(--jalsa-reveal-duration) cubic-bezier(0.2, 0, 0, 1),
    transform var(--jalsa-reveal-duration) cubic-bezier(0.2, 0, 0, 1);
  transition-delay: var(--jalsa-reveal-delay, 0ms);
  will-change: opacity, transform;
}
.jalsa-reveal-in {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Stagger within a run of siblings, expressed as classes rather than inline styles so the
 * script never rewrites an authored `style` attribute. */
.jalsa-reveal--d1 { --jalsa-reveal-delay: 70ms; }
.jalsa-reveal--d2 { --jalsa-reveal-delay: 140ms; }
.jalsa-reveal--d3 { --jalsa-reveal-delay: 210ms; }
.jalsa-reveal--d4 { --jalsa-reveal-delay: 280ms; }

/* ------------------------------------------------------- hover / micro-interactions --
 * Scoped behind `hover: hover` so a touch device never latches a stuck hover state, and
 * behind `no-preference` so reduced-motion users see none of it. The lift is a `transform`
 * (paint only, no reflow) and the shadow is a `filter` — deliberately NOT `box-shadow`,
 * so the existing sheets keep ownership of every card's authored shadow. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .event-card,
  .program-card,
  .gallery-tile,
  .partner-card,
  .review-card,
  .calendar-map-card,
  .completion-card,
  .journal-card,
  .gp-slide,
  .state {
    transition:
      transform 0.22s cubic-bezier(0.2, 0, 0, 1),
      filter 0.22s ease,
      background-color 0.2s ease,
      box-shadow 0.2s ease,
      border-color 0.2s ease;
  }

  .event-card:hover,
  .program-card:hover,
  .gallery-tile:hover,
  .partner-card:hover,
  .review-card:hover,
  .calendar-map-card:hover,
  .completion-card:hover,
  .journal-card:hover,
  .gp-slide:hover,
  .state:hover {
    transform: translate3d(0, -4px, 0);
    filter: drop-shadow(0 12px 24px rgba(9, 32, 50, 0.16));
  }

  .button:hover,
  .button:focus-visible,
  .carousel-next:hover,
  .event-hero__primary:hover,
  .event-hero__secondary:hover {
    filter: drop-shadow(0 8px 18px rgba(9, 32, 50, 0.2));
  }
}

/* Smooth colour transition on links/buttons. Lower specificity than every authored rule,
 * so it only fills gaps instead of overriding a tuned transition. */
a {
  transition: color 0.18s ease;
}

/* ---------------------------------------------------- gold hairline dividers ----
 * `border-color` on elements that ALREADY carry a border — so the divider is re-tinted,
 * never re-sized. No `border-width` is introduced anywhere, which is what keeps this a
 * paint-only change that cannot shift a single box. */
.events,
.story,
.carousel,
.partner-section,
.event-grid,
.review-grid,
.event-card {
  border-color: var(--jalsa-hairline);
}

/* ------------------------------------------------------------- hero motion ----
 * A slow, indefinite drift of the hero's background image. Only `background-position` is
 * animated — the element's box, its children and the `--hero` / `--img` custom properties
 * the renderer owns are all untouched. Gated to a fine pointer on a wide viewport so the
 * continuous repaint never reaches the device class where it would cost frames.
 */
@keyframes jalsa-hero-drift {
  0%   { background-position: 50% 50%; }
  50%  { background-position: 52% 58%; }
  100% { background-position: 50% 50%; }
}

@media (prefers-reduced-motion: no-preference) and (hover: hover) and (pointer: fine) and (min-width: 761px) {
  .hero {
    animation: jalsa-hero-drift 32s ease-in-out infinite;
  }
}

/* ---------------------------------------------------------------- kill-switches --
 * Reduced motion is non-negotiable: no drift, no reveal transform, no petals. The
 * `!important`s are intentional — they must beat a currently-running animation. */
@media (prefers-reduced-motion: reduce) {
  .hero {
    animation: none !important;
  }
  .jalsa-petals {
    display: none !important;
  }
  .jalsa-reveal,
  .jalsa-reveal-in {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* Mobile gate: drop the continuous hero repaint and the petal canvas outright, and
 * downgrade the reveal to a cheap opacity-only fade (no translate, no stagger). */
@media (max-width: 760px), (pointer: coarse) {
  .hero {
    animation: none !important;
  }
  .jalsa-petals {
    display: none !important;
  }
  .jalsa-reveal {
    transform: none;
    transition: opacity 0.3s ease;
    transition-delay: 0ms;
  }
}
