/* Magic Scroll: sequence stage + liquid glass. Override the tokens, not the rules. */
:root {
  --ms-bg: #0b0b0c;          /* stage colour behind contain-fit frames; match the frame background */
  --ms-overlay-shift: 28px;  /* how far an overlay travels while fading in */
  --lg-radius: 28px;
  --lg-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
  --lg-fallback: rgba(28, 28, 32, 0.86); /* opaque surface for prefers-reduced-transparency */
}

/* ---------- sequence ---------- */
.ms-sequence { position: relative; height: 400vh; } /* JS sets the real height from options */
.ms-stage {
  position: sticky; top: 0; height: 100vh; height: 100svh; /* svh: no jump when the mobile URL bar hides */
  overflow: hidden; background: var(--ms-bg); contain: layout;
}
.ms-canvas, .ms-poster {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
}
.ms-poster { object-fit: contain; }
.ms-sequence[data-fit="cover"] .ms-poster { object-fit: cover; }
.ms-ready .ms-poster { visibility: hidden; }        /* canvas owns the stage once frame 1 is drawn */
.ms-failed .ms-canvas { display: none; }            /* frames broke: the poster stays, never blank */
.ms-failed .ms-poster { visibility: visible; }

/* Overlays are placed with top/left/inset/grid, never transform (transform is the motion channel). */
.ms-overlay {
  position: absolute; z-index: 2;
  opacity: var(--ms-vis, 0);
  transform: translateY(calc((1 - var(--ms-vis, 0)) * var(--ms-overlay-shift)));
  pointer-events: none;
}
.ms-overlay.ms-on { pointer-events: auto; }
.ms-overlay:not(.ms-on) { visibility: hidden; } /* skips paint, and the glass filter chain, while off */

/* Reduced motion (and no JS): no pin, no scrub. One still, every message stacked and readable. */
.ms-reduced { height: auto !important; }
@media (scripting: none) {
  .ms-sequence { height: auto !important; }
  .ms-stage, .ms-overlay, .ms-poster { visibility: visible; position: relative; inset: auto; height: auto; opacity: 1; transform: none; margin: 16px; }
}
.ms-reduced .ms-stage { position: relative; height: auto; min-height: 0; display: grid; gap: 16px; padding: 0 0 48px; }
.ms-reduced .ms-canvas, .ms-reduced .ms-poster { position: relative; inset: auto; height: 70vh; }
.ms-reduced .ms-canvas { grid-row: 1; }
.ms-reduced .ms-poster { grid-row: 1; grid-column: 1; }
.ms-reduced .ms-overlay { visibility: visible; position: relative; inset: auto; opacity: 1; transform: none; pointer-events: auto; margin: 0 16px; }

/* ---------- liquid glass (port of rdev/liquid-glass-react) ---------- */
.lg {
  border-radius: var(--lg-radius);
  /* never opacity/filter/clip-path/mask here: any of them becomes the backdrop root and the glass goes blind */
  transform: translate(var(--lg-tx, 0px), var(--lg-ty, 0px)) scale(var(--lg-sx, 1), var(--lg-sy, 1));
  transition: transform 0.2s ease-out;
}
.lg > :not(.lg-layer) { position: relative; z-index: 1; }
.lg-layer { position: absolute; inset: 0; border-radius: inherit; pointer-events: none; }
.lg-svg { width: 100%; height: 100%; overflow: hidden; box-shadow: var(--lg-shadow); } /* shadow lives here: the warp is clipped */
.lg-warp {
  overflow: hidden; background: var(--lg-tint, transparent);
  -webkit-backdrop-filter: blur(var(--lg-blur, 6px)) saturate(var(--lg-sat, 140%));
  backdrop-filter: blur(var(--lg-blur, 6px)) saturate(var(--lg-sat, 140%));
}
.lg--over-light .lg-warp { background: rgba(0, 0, 0, 0.2); }
.lg--over-light .lg-svg { box-shadow: 0 16px 70px rgba(0, 0, 0, 0.75); }
.lg-edge {
  padding: 1.5px; z-index: 2;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  box-shadow: 0 0 0 0.5px rgba(255,255,255,0.5) inset, 0 1px 3px rgba(255,255,255,0.25) inset, 0 1px 4px rgba(0,0,0,0.35);
  background: linear-gradient(var(--lg-angle, 135deg),
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,calc(var(--lg-e1, 0.12) + var(--lg-mx, 0) * 0.4)) 33%,
    rgba(255,255,255,calc(var(--lg-e2, 0.4) + var(--lg-mx, 0) * 0.6)) 66%,
    rgba(255,255,255,0) 100%);
}
/* rims blend normally: mix-blend-mode isolates the pane in Chromium and the backdrop shows through unblurred */
.lg-edge--screen { opacity: 0.2; }
.lg-edge--overlay { opacity: 0.5; --lg-e1: 0.32; --lg-e2: 0.6; }

/* Glass as a scroll overlay: fade the layers, not the pane (pane opacity would blind the backdrop). */
.ms-overlay.lg { opacity: 1; }
.ms-overlay.lg > * { opacity: var(--ms-vis, 0); }
.ms-overlay.lg > .lg-edge--screen { opacity: calc(var(--ms-vis, 0) * 0.2); }
.ms-overlay.lg > .lg-edge--overlay { opacity: calc(var(--ms-vis, 0) * 0.5); }
.ms-overlay.lg {
  transform: translate(var(--lg-tx, 0px), calc(var(--lg-ty, 0px) + (1 - var(--ms-vis, 0)) * var(--ms-overlay-shift)))
             scale(var(--lg-sx, 1), var(--lg-sy, 1));
}
.ms-reduced .ms-overlay.lg > * { opacity: 1; }
.ms-reduced .ms-overlay.lg > .lg-edge--screen { opacity: 0.2; }
.ms-reduced .ms-overlay.lg > .lg-edge--overlay { opacity: 0.5; }

@media (prefers-reduced-transparency: reduce) {
  .lg-warp { -webkit-backdrop-filter: none; backdrop-filter: none; filter: none !important; background: var(--lg-fallback); }
}
@media (prefers-reduced-motion: reduce) {
  .lg { transform: none !important; transition: none; }
}
