/* ==========================================================================
   AURORA LEDGER — generative data-art visualization
   Companion to Concept D (The World Ledger) and Concept B (Whale Reef).
   Same product, most abstract metaphor: no globe, no creatures — just
   generative northern-lights ribbons, driven purely by real ledger data.
   Palette: deep night sky + aurora spectrum (emerald green -> violet ->
   magenta), reserved for the canvas itself. Chrome stays restrained and
   near-monochrome so the light show is the only saturated thing on screen.
   ========================================================================== */

body.aurora-page {
  background: #05050c;
  overflow-x: hidden;
}

/* -------------------------------------------------------------------- */
/* Header                                                                */
/* -------------------------------------------------------------------- */
.aurora-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 30;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: var(--space-4) var(--space-6);
  background: linear-gradient(180deg, rgba(5, 5, 12, 0.92) 0%, rgba(5, 5, 12, 0) 100%);
  gap: var(--space-3) var(--space-4);
}
.aurora-header .brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--color-text);
  text-decoration: none;
  grid-column: 1;
  justify-self: start;
}
.aurora-header .aurora-nav { grid-column: 2; justify-self: center; }
.aurora-header .aurora-actions { grid-column: 3; justify-self: end; position: relative; display: flex; align-items: center; gap: var(--space-2); }
.aurora-header .brand svg { width: 28px; height: 28px; color: #7ee6c0; }

.aurora-sound-toggle {
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  border-radius: var(--radius-full);
  color: #b7ecd9;
  border: 1px solid rgba(126, 230, 192, 0.28);
  background: rgba(126, 230, 192, 0.06);
  transition: var(--transition-interactive);
  position: relative;
}
.aurora-sound-toggle svg { width: 16px; height: 16px; }
.aurora-sound-toggle:hover { color: #e4fff4; border-color: #7ee6c0; background: rgba(126, 230, 192, 0.12); }
.aurora-sound-toggle svg line { transition: opacity 150ms ease; }
.aurora-sound-toggle.is-on svg line { opacity: 0; }
.aurora-sound-toggle.is-on { color: #7ee6c0; border-color: #7ee6c0; background: rgba(126, 230, 192, 0.16); }

.aurora-ambient-toggle svg .icon-collapse { opacity: 0; }
.aurora-ambient-toggle svg .icon-expand,
.aurora-ambient-toggle svg .icon-collapse { transition: opacity 150ms ease; }
.aurora-ambient-toggle.is-on svg .icon-expand { opacity: 0; }
.aurora-ambient-toggle.is-on svg .icon-collapse { opacity: 1; }

/* -------------------------------------------------------------------- */
/* Ambient / screensaver mode                                           */
/* Hides every UI layer and lets the ribbons run full-bleed with live   */
/* data + a rotating real nature soundscape underneath — nothing here   */
/* touches state.                                                       */
/* -------------------------------------------------------------------- */
body.is-ambient .aurora-header,
body.is-ambient .aurora-intro,
body.is-ambient .aurora-panel,
body.is-ambient .aurora-legend,
body.is-ambient .aurora-hint,
body.is-ambient .whale-toast {
  opacity: 0 !important;
  pointer-events: none !important;
  transition: opacity 700ms ease;
}
body.is-ambient,
body.is-ambient .aurora-stage,
body.is-ambient #aurora-canvas {
  cursor: none;
}

.aurora-ambient-hint {
  position: fixed;
  left: 50%;
  bottom: var(--space-8);
  transform: translateX(-50%);
  z-index: 40;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  color: #d8fff0;
  background: rgba(5, 5, 12, 0.55);
  border: 1px solid rgba(126, 230, 192, 0.22);
  padding: var(--space-2) var(--space-5);
  border-radius: var(--radius-full);
  opacity: 0;
  pointer-events: none;
  transition: opacity 600ms ease;
  backdrop-filter: blur(6px);
}
.aurora-ambient-hint.is-visible { opacity: 1; }

.aurora-sound-toggle.is-on:not(.is-unlocked)::after {
  content: '';
  position: absolute;
  inset: -5px;
  border-radius: var(--radius-full);
  border: 1.5px solid rgba(126, 230, 192, 0.55);
  animation: aurora-cue-pulse 1.8s ease-out infinite;
  pointer-events: none;
}
@keyframes aurora-cue-pulse {
  0% { transform: scale(0.85); opacity: 0.9; }
  100% { transform: scale(1.55); opacity: 0; }
}

.sound-cue {
  /* Fixed at the bottom-right corner, raised well above the bottom-center
     caption (.aurora-hint, ~24px from the bottom), rather than anchored
     near the toggle button or centered under the header: that whole top
     band is contested — nav pills to the button's left, the live vitals
     panel starting almost flush with the header's bottom edge on the
     right, AND the real-time whale-payment toast (.whale-toast, also
     centered under the header) can appear at any moment since it fires on
     real ledger activity, not a fixed schedule. 110px of bottom clearance
     keeps this above the caption row while staying far below the panel's
     bottom edge — same fix applied to globe.css's equivalent cue. */
  position: fixed;
  top: auto;
  bottom: 110px;
  left: auto;
  right: 28px;
  transform: none;
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  padding: 7px 12px 7px 10px;
  border-radius: var(--radius-full);
  background: rgba(8, 14, 12, 0.92);
  border: 1px solid rgba(126, 230, 192, 0.3);
  color: #e4fff4;
  font-size: 12.5px;
  font-family: var(--font-mono);
  letter-spacing: 0.01em;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  opacity: 0;
  animation: aurora-cue-in 600ms ease 900ms forwards;
  transition: opacity 400ms ease;
  z-index: 20;
}
.sound-cue svg { width: 14px; height: 14px; color: #7ee6c0; flex-shrink: 0; }
.sound-cue.is-hidden { opacity: 0 !important; pointer-events: none; }
.sound-cue .short { display: none; }
@keyframes aurora-cue-in { to { opacity: 1; } }


/* -------------------------------------------------------------------- */
/* Stage                                                                 */
/* -------------------------------------------------------------------- */
.aurora-stage {
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  min-height: 640px;
  /* Defensive clip: see reef.css .reef-stage for why this guards the
     absolutely-positioned .aurora-panel against off-screen rendering. */
  overflow: hidden;
  background:
    radial-gradient(ellipse 90% 60% at 50% 0%, rgba(35, 30, 60, 0.5) 0%, transparent 60%),
    linear-gradient(180deg, #070712 0%, #050510 40%, #030308 100%);
}

#aurora-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.aurora-vignette {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: radial-gradient(ellipse 95% 95% at 50% 45%, transparent 45%, rgba(2, 2, 6, 0.6) 100%);
}

/* -------------------------------------------------------------------- */
/* Intro copy                                                            */
/* -------------------------------------------------------------------- */
.aurora-intro {
  position: absolute;
  top: calc(var(--space-16) + var(--space-10));
  left: var(--space-6);
  max-width: 460px;
  z-index: 10;
  pointer-events: none;
}
.aurora-intro .eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #b98bff;
}
.aurora-intro h1 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-xl);
  margin: var(--space-3) 0 var(--space-3);
  color: #f4fdf9;
  text-shadow: 0 0 30px rgba(126, 230, 192, 0.2);
}
.aurora-intro p {
  color: #cfe3dc;
  font-size: var(--text-sm);
  line-height: 1.65;
}
.aurora-intro .aurora-sound-note {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid rgba(126, 230, 192, 0.16);
  color: #b7ecd9;
}

/* -------------------------------------------------------------------- */
/* Vitals panel (glass, mirrors globe/reef panel conventions)            */
/* -------------------------------------------------------------------- */
.aurora-panel {
  position: absolute;
  top: var(--space-16);
  right: var(--space-6);
  z-index: 10;
  width: 280px;
  background: rgba(10, 8, 20, 0.66);
  border: 1px solid rgba(185, 139, 255, 0.18);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  box-shadow: 0 0 40px rgba(126, 230, 192, 0.05);
}
.aurora-panel .panel-title {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-faint);
  margin-bottom: var(--space-3);
}
.aurora-stat-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: var(--space-2) 0;
  border-top: 1px solid rgba(185, 139, 255, 0.10);
}
.aurora-stat-row:first-of-type { border-top: none; }
.aurora-stat-row .label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
.aurora-stat-row .value {
  font-family: var(--font-mono);
  font-weight: 600;
  color: #f4fdf9;
  font-size: var(--text-sm);
}
.aurora-stat-row .value.mono { color: #b6ecd9; }

.legend-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; flex: none; }
.legend-dot.pulse-live { background: #7ee6c0; box-shadow: 0 0 8px #7ee6c0; animation: dot-breathe 2.4s ease-in-out infinite; }
@keyframes dot-breathe { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }

.aurora-status {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid rgba(185, 139, 255, 0.10);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  line-height: 1.6;
}
.aurora-status.is-live { color: #7ee6c0; }

/* -------------------------------------------------------------------- */
/* Legend (bottom-left, whale strand colors)                             */
/* -------------------------------------------------------------------- */
.aurora-legend {
  position: absolute;
  bottom: var(--space-6);
  left: var(--space-6);
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}
.legend-item { display: flex; align-items: center; gap: var(--space-2); }
.swatch { width: 12px; height: 12px; border-radius: 50%; flex: none; }
.swatch-xrp { background: radial-gradient(circle, #d9fff0 0%, #7ee6c0 45%, transparent 75%); box-shadow: 0 0 8px #7ee6c0; }
.swatch-stable { background: radial-gradient(circle, #fbe9ff 0%, #d68bff 45%, transparent 75%); box-shadow: 0 0 8px #d68bff; }

/* -------------------------------------------------------------------- */
/* Hint + loading                                                        */
/* -------------------------------------------------------------------- */
.aurora-hint {
  position: absolute;
  bottom: var(--space-6);
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  opacity: 0;
  animation: aurora-hint-in 700ms ease 1000ms forwards;
  transition: opacity 400ms ease;
  text-align: center;
  white-space: nowrap;
}
.aurora-hint.is-hidden { opacity: 0 !important; }
@keyframes aurora-hint-in { to { opacity: 1; } }
.aurora-hint svg { width: 16px; height: 16px; flex: none; }

.aurora-loading {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 25;
  background: #050510;
  transition: opacity 600ms ease;
  flex-direction: column;
  gap: var(--space-3);
}
.aurora-loading.is-hidden { opacity: 0; pointer-events: none; }
.aurora-loading .spinner {
  width: 34px; height: 34px;
  border-radius: 50%;
  border: 2px solid rgba(185, 139, 255, 0.18);
  border-top-color: #7ee6c0;
  animation: aurora-spin 900ms linear infinite;
}
.aurora-loading p { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--color-text-faint); letter-spacing: 0.05em; text-transform: uppercase; }
@keyframes aurora-spin { to { transform: rotate(360deg); } }

/* -------------------------------------------------------------------- */
/* Whale toast (transient notice when a whale strand appears)            */
/* -------------------------------------------------------------------- */
.whale-toast {
  position: absolute;
  top: var(--space-16);
  left: 50%;
  transform: translateX(-50%) translateY(-12px);
  z-index: 15;
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-full);
  background: rgba(10, 8, 20, 0.78);
  border: 1px solid rgba(185, 139, 255, 0.3);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: #f4fdf9;
  letter-spacing: 0.02em;
  opacity: 0;
  pointer-events: none;
  transition: opacity 320ms cubic-bezier(0.16, 1, 0.3, 1), transform 320ms cubic-bezier(0.16, 1, 0.3, 1);
  white-space: nowrap;
}
.whale-toast.is-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
/* Set by aurora.js's positionToast() when the header+intro leave too
   little vertical room on mobile for the toast to render without
   overlapping the intro's eyebrow label — see the comment there. */
.whale-toast.toast-no-room {
  opacity: 0 !important;
  pointer-events: none !important;
}

/* -------------------------------------------------------------------- */
/* Sources footer                                                        */
/* -------------------------------------------------------------------- */
.aurora-sources {
  max-width: var(--content-default);
  margin: 0 auto;
  padding: var(--space-8) var(--space-6) var(--space-16);
  font-size: var(--text-xs);
  line-height: 1.7;
  color: var(--color-text-faint);
  background: #05050c;
}
.aurora-sources a { color: var(--color-text-muted); }
.aurora-sources strong { color: var(--color-text-muted); }
/* Embedded in the flagship, this footer sits below the iframe's 100vh
   crop with no way for a mouse/scroll user to reach it (wheel scroll
   drives the flagship's own act-to-act scroll, not this iframe's inner
   overflow) — but it stayed keyboard-tabbable, so Tab would silently
   auto-scroll the iframe to reveal content no sighted scroller could
   ever see. Hide it outright in embed mode; the flagship's own Proof
   act already covers this methodology at the top level. */
.lv-embedded .aurora-sources { display: none; }

/* -------------------------------------------------------------------- */
/* Responsive                                                            */
/* -------------------------------------------------------------------- */
@media (max-width: 1080px) {
  .aurora-panel { width: 240px; }
}

/* Two independently-positioned, centered/nowrap elements — the live
   whale-payment toast (fires on real ledger activity, any time) and the
   bottom caption hint — each assumed they had the full width to themselves.
   Between roughly 760px (where both switch to mobile layouts) and ~1000px
   they don't: the toast's centered nowrap pill runs into the narrowed
   vitals panel's left edge, and the hint's centered nowrap caption runs
   into the bottom-left legend's right edge. Confirmed by measurement at
   761-1000px (both pairs overlap) vs 1024px+ (clear). Fix: let each wrap
   within a viewport-relative max-width in exactly that range, instead of
   waiting for the mobile breakpoint to stop using nowrap. */
@media (max-width: 1024px) and (min-width: 761px) {
  .whale-toast {
    /* The header's centered nav wraps to a second line anywhere below
       ~970px (grid center column runs out of room for all five pills),
       taking the header from ~72px to ~119.5px tall — right where the
       toast (top: 96px in the base rule) sits, so the wrapped second nav
       row showed through behind/under the toast pill. 132px clears the
       tallest measured wrapped header (119.5px) with margin, applied
       across the whole range since a few extra px of drop when the
       header is still one line is harmless. */
    top: 132px;
    max-width: calc(100vw - 560px);
    white-space: normal;
    text-align: center;
  }
  .aurora-hint {
    max-width: calc(100vw - 480px);
    white-space: normal;
    text-align: center;
  }
}

@media (max-width: 760px) {
  .aurora-header { align-items: flex-start; padding: var(--space-3) var(--space-4); }
  /* The intro copy and data panel used to both be absolutely positioned
     inside a fixed-height (100dvh) stage — one anchored from the top, one
     from the bottom, each free to grow toward the other. On narrow screens
     the intro's text ran long enough to collide with the panel, so on
     mobile they instead flow normally, stacked one after another, and the
     stage grows to fit them while the canvas stays fixed full-bleed behind. */
  /* padding-top clears both the wrapped header (logo + pills + buttons)
     and the "tap to hear" sound-cue bubble that floats just below it
     before first interaction — 9.5rem only cleared the header itself and
     let the cue bubble overlap the eyebrow label underneath it. */
  .aurora-stage { height: auto; min-height: 100dvh; padding-top: 13rem; padding-bottom: var(--space-8); }
  /* Embedded acts have no header to clear (it's hidden entirely, see the
     html.lv-embedded rule above) — the 13rem clearance above would just
     leave a dead empty gap at the top of the act inside the flagship. */
  html.lv-embedded .aurora-stage { padding-top: var(--space-6); }
  #aurora-canvas { position: fixed; inset: 0; z-index: 0; }
  .aurora-vignette { position: fixed; inset: 0; z-index: 1; }
  .aurora-intro {
    position: relative;
    top: auto; left: auto; right: auto;
    max-width: none;
    margin: 0 var(--space-4) var(--space-6);
    pointer-events: auto;
    cursor: pointer;
  }
  .aurora-intro .overlay-hide-hint { display: flex; }
  .aurora-panel {
    position: relative;
    top: auto; bottom: auto; left: auto; right: auto;
    width: auto;
    margin: 0 var(--space-4);
  }
  .aurora-legend { display: none; }
  .aurora-hint { display: none; }
  .aurora-loading { position: fixed; }
  /* The header wraps across 3+ lines on narrow phones (measured up to
     196px tall at 320px width) as logo/pills reflow, so a fixed top
     offset landed the toast directly on top of the wrapped nav pills at
     several widths (confirmed at 390px: toast text overlapping "Whale
     Reef"/"Vitals Monitor"). A fixed *bottom* offset doesn't work either
     — the vitals panel flows in-page on mobile and is often sitting in
     the initial viewport's bottom band already (confirmed at 390×844:
     toast covering "Reading the…"/"Close rate"). Neither corner is safe
     with a static number since header height varies continuously with
     width, so aurora.js positions `top` inline via the header's actual
     measured height (see positionToast() there) — this is just the
     pre-JS/no-JS fallback, generous enough to clear the tallest measured
     header (196px) with margin. */
  .whale-toast { position: fixed; top: 210px; bottom: auto; max-width: calc(100% - var(--space-8)); white-space: normal; text-align: center; }
  /* On mobile the panel flows normally after the intro instead of being
     pinned to a fixed corner, and the page is taller than one viewport,
     so the live vitals panel is often already sitting in the same
     bottom-right area a fixed cue would occupy — confirmed by measurement
     at 390×844 (panel visible within the very first viewport, directly
     under where the cue would sit). No fixed corner is reliably clear
     with a static value, so aurora.js measures the header's actual
     rendered bottom edge at runtime and pins the cue there instead (same
     technique already used for the whale-payment toast below) — and
     hides it outright if that gap is ever too tight to hold it, rather
     than let it overlap the intro copy. */
  .sound-cue {
    top: 0; bottom: auto; left: 50%; right: auto;
    transform: translateX(-50%);
    font-size: 11px;
    padding: 6px 11px 6px 9px;
  }
  .sound-cue .full { display: none; }
  .sound-cue .short { display: inline; }
  .sound-cue.no-room { opacity: 0 !important; pointer-events: none; }
}

@media (prefers-reduced-motion: reduce) {
  .legend-dot.pulse-live { animation: none; }
}

/* Sibling-concept navigation (added so visitors can browse all concepts) */
.aurora-nav {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
@media (max-width: 640px) {
  .aurora-header { grid-template-columns: 1fr; justify-items: center; row-gap: var(--space-2); }
  .aurora-header .brand { justify-self: center; }
  .aurora-header .aurora-nav { grid-column: 1; }
  .aurora-header .aurora-actions { grid-column: 1; justify-self: center; }
  .aurora-nav { width: 100%; justify-content: center; gap: var(--space-2); }
}

/* -------------------------------------------------------------------- */
/* Embedded mode — this page nested as one act inside the flagship's    */
/* single scroll journey (index.html). Hides the logo + cross-page pill */
/* nav (redundant inside the flagship's own header), keeps this act's    */
/* own sound/ambient toggle so it still feels alive on its own.          */
/* -------------------------------------------------------------------- */
html.lv-embedded .aurora-header {
  /* The flagship page's own header already supplies an equivalent
     global sound toggle, immersive toggle, and live-status badge --
     keeping this page's own header visible too would show two of
     each control on screen at once near the top of this act, the
     clearest possible tell that this is four pages stitched
     together rather than one converged experience. Audio unlock
     and mute/duck are already driven by postMessage from the
     parent (see embed-bridge.js), so hiding this header loses no
     functionality inside the flagship. */
  display: none !important;
}

/* Panel-hide toggle — a small always-tappable button that only ever
   hides/shows the intro copy + vitals panel, nothing else (no wake lock,
   no sound change, no cursor hiding). It only renders when embedded in
   the flagship (html.lv-embedded), because that's the one context where
   the header — and its full ambient-mode toggle — is hidden and there is
   otherwise no way to see the aurora unobstructed. Standalone, the
   header's own ambient toggle already covers this. */
.lv-panel-toggle {
  display: none;
}
html.lv-embedded .lv-panel-toggle {
  display: flex;
  position: fixed;
  top: var(--space-3);
  right: var(--space-3);
  z-index: 40;
  width: 36px;
  height: 36px;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  background: rgba(6, 16, 20, 0.72);
  border: 1px solid rgba(126, 230, 192, 0.22);
  color: rgba(214, 245, 240, 0.8);
  cursor: pointer;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  transition: color 200ms ease, border-color 200ms ease, background 200ms ease;
}
.lv-panel-toggle svg { width: 17px; height: 17px; position: absolute; }
.lv-panel-toggle .icon-eye-off { opacity: 0; }
.lv-panel-toggle.is-hidden .icon-eye { opacity: 0; }
.lv-panel-toggle.is-hidden .icon-eye-off { opacity: 1; }
.lv-panel-toggle.is-hidden {
  color: #7ee6c0;
  border-color: #7ee6c0;
  background: rgba(126, 230, 192, 0.16);
}
body.lv-panel-hidden .aurora-intro,
body.lv-panel-hidden .aurora-panel {
  opacity: 0 !important;
  pointer-events: none !important;
  transition: opacity 320ms ease;
}
