/* =========================================================
   home.css — VioLev homepage hero (the drifting SVG doors)

   The front door: three SVG "doors" — History / Journey / Adventure —
   drift, mingle, hide, and return over a calm violet-dark wash. The
   doors ARE the navigation. Modern-minimal-violet; abstract forms.

   Extracted from the hero's inline <style> into the house per-section
   CSS slot (loaded via $page_css), matching journey.css / history.css /
   adventure.css. The motion ENGINE stays inline in index.php — it's
   behavior, not style.

   Built on the shared single-screen fit-to-viewport shell + portrait
   gate (same shell as History / Journey / Adventure). Bones at rest,
   violet on interaction — the house thesis.
   ========================================================= */

/* ---- fit-to-viewport: the whole composition lives in ONE screen and
        scales with the resolution. The page never scrolls — not because
        anything is clipped, but because it's SIZED to fit. Body is exactly
        one viewport tall; the stage fills the gap between the floating
        header (which overlays the top) and the always-visible footer. ---- */
body { height: 100vh; height: 100dvh; display: flex; flex-direction: column; }
main { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.site-footer { flex: 0 0 auto; }   /* pinned at the absolute bottom, always visible */

/* ---- stage: fills main; video/wash sit behind the doors.
        overflow:hidden here is the DOOR-HIDE boundary (doors clip as they
        drift off the edge) — NOT a no-scroll hack. ---- */
.stage {
  position: relative;
  flex: 1 1 auto; min-height: 0;
  overflow: hidden;
  isolation: isolate;            /* anchor the z-layers here: wash → video(-1) → doors(1) */
  /* calm violet-dark wash — low contrast, violet as faint light */
  background:
    radial-gradient(120% 90% at 50% 18%, rgba(139,92,255,.10), transparent 60%),
    radial-gradient(90% 70% at 80% 100%, rgba(91,51,201,.10), transparent 55%),
    linear-gradient(180deg, var(--abyss), var(--void));
}
.stage-video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover;
  opacity: .20;                        /* always on — tune .4–.6 to taste */
  transition: opacity 1250ms linear;  /* the seam fade ramp (1.25s each way) */
  z-index: var(--z-bg);
}
.stage-video.seam { opacity: 0; }     /* faded out across the loop seam */

/* ---- the doors ---- */
.door {
  position: absolute; top: 0; left: 0;       /* moved purely by translate */
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  text-decoration: none; color: inherit;
  cursor: pointer; user-select: none;
  opacity: 0;                                /* hidden until the engine places it */
  will-change: transform;
  z-index: var(--z-base);
}
.door.is-live { opacity: 1; }                /* engine turns this on at entry */

.door-glyph svg {
  width: clamp(72px, 9vmin, 132px); height: clamp(72px, 9vmin, 132px);
  display: block; transform-origin: 50% 50%;
  fill: var(--violet-bright); stroke: var(--violet-bright);
  stroke-width: 3; stroke-linecap: round; stroke-linejoin: round;
  filter: drop-shadow(0 0 10px rgba(139,92,255,.35));
  transition: filter var(--transition-medium), transform var(--transition-medium), opacity var(--transition-medium);
}

/* ---- per-door TRAVEL effects: each glyph has its own life while it drifts.
        Hung on the inner svg so the engine's translate on .door is never
        touched. Adventure blooms its glow; Journey turns; History breathes
        between 50% and 125%. They settle on freeze (below) and are killed
        entirely under reduced-motion (also below). ---- */
#door-adventure .door-glyph svg { animation: adv-glow 2.8s ease-in-out infinite; }
#door-journey   .door-glyph svg { animation: jrn-turn 7s linear infinite; }
#door-history   .door-glyph svg { animation: his-breathe 3.6s ease-in-out infinite; }

/* Adventure's bloom is a real DISC OF LIGHT behind the glyph — a thin-stroked
   compass has too little ink for a drop-shadow to read, so the swell lives in
   a radial halo that grows + brightens in sync with a lighter stroke glow. */
#door-adventure .door-glyph { position: relative; }
#door-adventure .door-glyph svg { position: relative; z-index: 1; }
#door-adventure .door-glyph::before {
  content: ""; position: absolute; left: 50%; top: 50%; z-index: 0;
  width: 160%; height: 160%; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle,
    rgba(212,194,255,.68) 0%, rgba(168,123,255,.44) 34%, rgba(139,92,255,0) 70%);
  transform: translate(-50%, -50%) scale(.4);
  will-change: transform, opacity;
  animation: adv-bloom 2.8s ease-in-out infinite;
}

@keyframes adv-glow {
  0%, 100% { filter: drop-shadow(0 0 5px rgba(139,92,255,.45)); }
  50%      { filter: drop-shadow(0 0 16px rgba(212,194,255,1)) drop-shadow(0 0 34px rgba(168,123,255,.8)); }
}
@keyframes adv-bloom {
  0%, 100% { opacity: .20; transform: translate(-50%, -50%) scale(.40); }
  50%      { opacity: 1;   transform: translate(-50%, -50%) scale(1.25); }
}
@keyframes jrn-turn { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes his-breathe { 0%, 100% { transform: scale(.5); } 50% { transform: scale(1.25); } }

/* hover/freeze: the engine adds .is-frozen to the stage when it freezes all
   three. Travel stops, every glyph (and Adventure's bloom) settles to a calm
   rest state, and the hovered/focused one lifts + brightens for the click.
   (plain :hover — no media guard, per the Session-2 footer lesson.) */
.stage.is-frozen .door-glyph svg {
  animation: none; transform: scale(1); opacity: 1;
  filter: drop-shadow(0 0 12px rgba(139,92,255,.50));
}
.stage.is-frozen #door-adventure .door-glyph::before {
  animation: none; opacity: .55; transform: translate(-50%, -50%) scale(.9);
}
.stage.is-frozen .door:hover .door-glyph svg,
.door:focus-visible .door-glyph svg {
  transform: scale(1.08);
  filter: drop-shadow(0 0 22px rgba(168,123,255,.80));
}

/* reduced motion -> no travel life at all, matching the static-doors branch
   in the engine. Honored literally; no motion-lite. Adventure's bloom holds
   as a faint static halo (no pulse). */
@media (prefers-reduced-motion: reduce) {
  #door-adventure .door-glyph svg,
  #door-journey   .door-glyph svg,
  #door-history   .door-glyph svg { animation: none; }
  #door-adventure .door-glyph::before {
    animation: none; opacity: .32; transform: translate(-50%, -50%) scale(.7);
  }
}

.door-label {
  font-family: var(--mono); font-size: .72rem; letter-spacing: .28em;
  text-transform: uppercase; color: var(--mist);
  opacity: 0; transform: translateY(4px);
  transition: opacity var(--transition-medium), transform var(--transition-medium);
  text-shadow: var(--glow-violet-soft);
}
/* label surfaces when the engine says we're armed + hovered/focused */
.door.show-label .door-label,
.door:focus-visible .door-label { opacity: 1; transform: none; }

.door:focus-visible { outline: 2px solid var(--violet); outline-offset: 10px; border-radius: var(--radius-md); }

/* ---- portrait gate (phones + tablets): a rotate-to-landscape wall.
        This composition is landscape-only by design — a showcase, not a
        reach play. Touch + portrait only, so desktop never sees it. ---- */
.rotate-nag { display: none; }
@media (orientation: portrait) and (pointer: coarse) {
  .rotate-nag {
    display: flex; position: fixed; inset: 0; z-index: 9999;
    flex-direction: column; align-items: center; justify-content: center;
    gap: 18px; padding: 40px; text-align: center; background: var(--void);
  }
  .rotate-nag-title {
    font-family: var(--display); font-weight: 600;
    font-size: clamp(1.4rem, 7vw, 2rem); color: var(--mist);
  }
  .rotate-nag-sub {
    font-family: var(--mono); font-size: .72rem; letter-spacing: .14em;
    text-transform: uppercase; color: var(--haze); max-width: 32ch; line-height: 1.7;
  }
}
