/* ==========================================================================
   HOME COPY of design/v3-lab/oracle-common.css, for Home's Enter the Oracle
   (option A). One change from the lab file: the placeholder url() is next to
   this file. Keep the two in step.

   Enter the Oracle lab: shared styles for oracle-a.html, oracle-b.html and
   oracle-c.html. Everything is prefixed oc-. Pair with oracle-common.js.

   Fixed scene + footer over it (peachweb's mechanism in plain CSS, no fixed
   layer, works in Bricks):

     <div class="oc-scene">
       <div class="oc-stage">                      sticky, one window tall: the picture
         <div class="oc-media"><canvas class="oc-canvas"></canvas></div>
         ...layers (vortex, glow)...
         <div class="oc-veil"></div>
       </div>
       <section class="oc-track">...</section>     starts at the top of the stage and scrolls over it;
                                                   its height (--oc-track) is the scroll the scene plays for
       <div class="oc-over">newsletter + footer</div>   rides up over the held scene, "and that's the end"
     </div>

   The stage stays stuck from the moment its top reaches the top of the window
   until the end of .oc-scene, which is the end of the page, so the scene never
   scrolls away. Before that it rises with the page like any section.
   ========================================================================== */

/* Two window heights (7 Oct). A phone's browser bars collapse as the reader scrolls, so the
   window has a small height (bars showing) and a large one (bars away). The stage, the picture,
   fills the LARGE one: sized by the small one it left a flat strip under the picture for the
   whole scene once the bars had gone (the owner, 7 Oct: the section "not quite right" on a
   phone). Words and buttons that must stay clear of the bars sit by --oc-vh-ui, the SMALL one
   (Home's .oa-text). On a desktop the two are the same height. */
.oc-scene { position: relative; --oc-vh: 100vh; --oc-vh-ui: 100vh; }
@supports (height: 100lvh) { .oc-scene { --oc-vh: 100lvh; --oc-vh-ui: 100svh; } }

.oc-stage { position: sticky; top: 0; z-index: 0; height: var(--oc-vh); overflow: hidden;
            background: var(--oc-ground, #000); }
/* the block after the stage starts at the stage's top, so it scrolls over it */
.oc-stage + * { margin-top: calc(-1 * var(--oc-vh)); }
.oc-track { position: relative; z-index: 1; height: var(--oc-track, 200vh); pointer-events: none; }
.oc-track a, .oc-track button, .oc-track input { pointer-events: auto; }
.oc-over { position: relative; z-index: 2; }

/* the picture: a placeholder (average colour + the 64 px blurred still) until the
   canvas has drawn its first frame, then the canvas fades in over it. The player
   draws that first frame as soon as the section is near, so the fade is normally
   over before it scrolls into view; .is-instant skips it when the canvas draws the
   moment it arrives on screen (a jump to the section, a reload there). */
.oc-media { position: absolute; inset: 0; overflow: hidden;
            background: #383638 url("oracle-portal-f0-placeholder.webp") center / cover no-repeat; }
.oc-canvas { display: block; width: 100%; height: 100%; opacity: 0; transition: opacity 400ms ease; }
.oc-canvas.is-drawn { opacity: 1; }
.oc-canvas.is-instant { transition: none; }
/* an <img> resting still (reduced motion, or no JS) fills like the canvas */
.oc-still { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* darkens the held scene as the newsletter and footer ride over it (OracleCommon.footerOver) */
.oc-veil { position: absolute; inset: 0; z-index: 5; pointer-events: none; background: #000; opacity: 0; }

/* an overlay placed on a box of the picture (OracleCommon.place): the vortex, a glow */
.oc-layer { position: absolute; pointer-events: none; }

/* ---------------- vortex placeholder (code only, until assets/oracle/vortex.json exists) ----------------
   Two slow counter-turning conic swirls and a warm core, masked soft to the doorway.
   Only transform animates, on the compositor. Opacity is var(--oc-vortex) (0..1), set by the page. */
.oc-vortex { position: absolute; pointer-events: none; overflow: hidden; opacity: var(--oc-vortex, 0);
             mix-blend-mode: screen; contain: strict; }
.oc-vortex::before, .oc-vortex::after { content: ""; position: absolute; left: 50%; top: 50%;
             width: 190%; aspect-ratio: 1; border-radius: 50%; will-change: transform; }
.oc-vortex::before {
  background:
    radial-gradient(closest-side, rgba(255, 236, 205, 0.95), rgba(255, 196, 140, 0.45) 22%, rgba(255, 170, 120, 0) 62%),
    repeating-conic-gradient(from 0deg, rgba(255, 214, 170, 0) 0deg, rgba(255, 214, 170, 0.28) 14deg,
                             rgba(255, 214, 170, 0) 34deg, rgba(210, 170, 255, 0.16) 50deg, rgba(255, 214, 170, 0) 72deg);
  -webkit-mask: radial-gradient(closest-side, #000 18%, rgba(0, 0, 0, 0.55) 45%, transparent 72%);
          mask: radial-gradient(closest-side, #000 18%, rgba(0, 0, 0, 0.55) 45%, transparent 72%);
  animation: oc-spin 22s linear infinite;
}
.oc-vortex::after {
  background: repeating-conic-gradient(from 90deg, rgba(255, 244, 225, 0) 0deg, rgba(255, 244, 225, 0.18) 9deg,
                                       rgba(255, 244, 225, 0) 26deg);
  -webkit-mask: radial-gradient(closest-side, transparent 8%, #000 30%, transparent 64%);
          mask: radial-gradient(closest-side, transparent 8%, #000 30%, transparent 64%);
  animation: oc-spin-back 34s linear infinite;
}
.oc-vortex.is-paused::before, .oc-vortex.is-paused::after { animation-play-state: paused; }
@keyframes oc-spin { from { transform: translate(-50%, -50%) rotate(0deg); } to { transform: translate(-50%, -50%) rotate(360deg); } }
@keyframes oc-spin-back { from { transform: translate(-50%, -50%) rotate(0deg); } to { transform: translate(-50%, -50%) rotate(-360deg); } }
/* a real vortex clip (video or canvas) inside the same box */
.oc-vortex > video, .oc-vortex > canvas { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.oc-vortex:has(> video, > canvas)::before, .oc-vortex:has(> video, > canvas)::after { content: none; }

/* ---------------- text entrance (OracleCommon.entrance) ----------------
   Items are [data-oc-in]. Hidden only when JS runs (.js on <html>), so the text
   is always there without it. The JS sets --oc-from / --oc-filter / --oc-delay /
   --oc-dur per item. */
.js .oc-in [data-oc-in] {
  opacity: 0; transform: var(--oc-from, translate3d(0, 24px, 0)); filter: var(--oc-filter, none);
  transition: opacity var(--oc-dur, 600ms) ease var(--oc-delay, 0ms),
              transform var(--oc-dur, 600ms) cubic-bezier(0.16, 1, 0.3, 1) var(--oc-delay, 0ms),
              filter var(--oc-dur, 600ms) ease var(--oc-delay, 0ms);
}
.js .oc-in[data-oc-mode="doorway"] [data-oc-in]:first-child { transform-origin: 50% 50%; will-change: transform, opacity, filter; }
.js .oc-in.is-in [data-oc-in] { opacity: 1; transform: none; filter: none; }
/* leaving (scrolling back above the text point): one quick fade, no stagger. Without this the
   line and the button would wait out their entrance delay before going, and could still be
   showing when the reader scrolls down again. */
.js .oc-in:not(.is-in):not(.is-scrub) [data-oc-in] { transition-delay: 0ms; transition-duration: 240ms; }
.js .oc-in.is-scrub [data-oc-in] { transition: none; }
.js .oc-in[data-oc-mode="fade"] [data-oc-in] { transform: none; }

/* ---------------- reduced motion ----------------
   No swirl, no transitions, the text simply there. Each page decides its
   layout; the brainstorm suggests the bloom still (.oc-still, or the player's
   resting frame) with the text on it, and no pin or scrub. */
@media (prefers-reduced-motion: reduce) {
  .js .oc-in [data-oc-in] { opacity: 1; transform: none; filter: none; transition: none; }
  .oc-vortex::before, .oc-vortex::after { animation: none; }
  .oc-canvas { transition: none; }
}
.is-reduced .oc-in [data-oc-in] { opacity: 1 !important; transform: none !important; filter: none !important; transition: none !important; }
.is-reduced .oc-vortex::before, .is-reduced .oc-vortex::after { animation: none; }

/* ---------------- lab readout (optional, bottom right) ---------------- */
.oc-lab { position: fixed; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom, 0px)); z-index: 1000;
          max-width: min(360px, calc(100vw - 24px)); padding: 10px 12px; border-radius: 10px;
          background: rgba(0, 0, 0, 0.72); color: #e8f9ff; font: 12px/1.45 ui-monospace, SFMono-Regular, Menlo, monospace;
          -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.oc-lab[hidden] { display: none; }
.oc-lab b { color: #fff; font-weight: 600; }
.oc-lab a { color: #ffe8e8; text-decoration: underline; }
