/* ==========================================================================
   이음교육저널 — Motion layer (redesign track C)
   Layered on top of kit.css/home.css. Everything here is gated behind
   .motion-on, which motion.js adds only when the user allows motion
   (prefers-reduced-motion: no-preference). No JS / reduced motion =
   the fully static journal page, unchanged.
   ========================================================================== */

/* ── Scroll progress rule ─────────────────────────────────────────────── */
.read-progress{
  position:fixed;top:0;left:0;width:100%;height:2px;
  background:var(--color-accent);transform-origin:0 50%;transform:scaleX(0);
  z-index:201;pointer-events:none
}

/* ── Scroll reveal ────────────────────────────────────────────────────── */
.motion-on [data-reveal]{
  opacity:0;transform:translateY(26px);
  transition:opacity .6s var(--ease-out),transform .7s var(--ease-out);
  transition-delay:var(--rd,0ms)
}
.motion-on [data-reveal].is-in{opacity:1;transform:none}

/* ── Hero title — masked per-word rise ──────────────────────────────────
   motion.js splits [data-split] into .hl-line > .hl-word runs, preserving
   whitespace text nodes between words (the split-word spacing fix). */
.motion-on .hero-title .hl-line{display:block;overflow:hidden;padding:.02em .08em .1em;margin:-.02em -.08em -.1em}
.motion-on .hero-title .hl-word{
  display:inline-block;transform:translateY(115%);
  transition:transform .9s var(--ease-out);transition-delay:var(--d,0ms)
}
.motion-on .hero-title.is-in .hl-word{transform:none}

/* ── Hero orbit sculpture (hero-3d.js mounts into .hero-orbit) ────────── */
.hero-side{display:grid;gap:clamp(1.5rem,3.5vw,2.75rem);align-content:center;justify-items:stretch}
.hero-side .editors-note{max-width:none;justify-self:stretch}
/* Squares stay aspect-ratio:1. A width-based margin-top percentage on a 2:1
   stage lands above the box, so each disc is centered with top/left 50% +
   translate(-50%,-50%). rotateX/rotateZ compose after that, about the box
   center. The glow is the stage height so the fade is not clipped. 이음 keeps
   the -54% glyph lift.
   Stage stays a layout box only (design review 2026-10-02). */
.hero-orbit{
  position:relative;width:min(100%,420px);aspect-ratio:2/1;
  margin-inline:auto;user-select:none
}
.hero-orbit__glow{
  position:absolute;left:50%;top:50%;width:50%;aspect-ratio:1;border-radius:50%;
  transform:translate(-50%,-50%);
  background:radial-gradient(circle at 50% 50%,rgb(from var(--color-accent) r g b / .12),rgb(from var(--color-accent) r g b / 0) 62%);
  pointer-events:none
}
.hero-orbit__ring{
  position:absolute;left:50%;top:50%;width:78%;aspect-ratio:1;
  transform:translate(-50%,-50%) rotateX(64deg) rotateZ(-8deg);
  border:1px solid rgb(from var(--color-accent) r g b / .30);
  border-radius:50%;pointer-events:none
}
.hero-orbit__ring--b{
  width:62%;
  transform:translate(-50%,-50%) rotateX(64deg) rotateZ(52deg);
  border-color:rgb(from var(--color-accent) r g b / .16)
}
.hero-orbit__ring--c{
  width:46%;
  transform:translate(-50%,-50%);
  border-style:dashed;border-color:rgb(from var(--color-accent) r g b / .14)
}
.hero-orbit__core{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-54%);
  font-family:var(--font-serif);font-weight:600;letter-spacing:-.02em;
  font-size:clamp(2.6rem,4.4vw,3.9rem);color:var(--color-accent-dark);
  pointer-events:none
}
.hero-orbit__word{
  position:absolute;top:50%;left:50%;white-space:nowrap;
  font-family:var(--font-serif);font-weight:500;letter-spacing:-.01em;
  font-size:clamp(.95rem,1.7vw,1.3rem);color:var(--color-accent)
}
.motion-on .hero-orbit__word{will-change:transform,opacity}

/* ── Interactive touches ──────────────────────────────────────────────── */
.motion-on [data-magnetic]{transform:translate(var(--mx,0px),var(--my,0px));transition:transform .22s var(--ease-out)}
.motion-on [data-magnetic]:active{transform:translate(var(--mx,0px),var(--my,0px)) scale(.98)}
.motion-on [data-tilt]{transform:perspective(900px);transition:transform .3s var(--ease-out)}
.motion-on [data-tilt].is-tilting{transition:transform .12s ease-out}
/* Still-photo lift: quiet 3% scale, long ease — editorial, not bouncy */
.motion-on .story-lead__media img,
.motion-on .story-row__thumb img{
  transition:transform .6s var(--ease-out)
}
.motion-on .story-lead:hover .story-lead__media img{transform:scale(1.035)}
.motion-on .story-row:hover .story-row__thumb img{transform:scale(1.05)}

/* ── Responsive ───────────────────────────────────────────────────────── */
@media (max-width:1040px){
  .hero-orbit{width:min(100%,340px)}
}
@media (max-width:640px){
  .hero-orbit{width:min(100%,260px)}
  .motion-on [data-reveal]{transform:translateY(18px)}
}

/* ── Reduced motion / no-JS safety net ──────────────────────────────────
   motion.js never adds .motion-on under reduced motion, but keep the
   CSS-level guarantee so a mid-session OS change also settles safely. */
@media (prefers-reduced-motion:reduce){
  .read-progress{display:none}
  .motion-on [data-reveal],
  .motion-on .hero-title .hl-word{opacity:1 !important;transform:none !important;transition:none !important}
  .hero-orbit__word{position:static;display:inline-block;margin:0 .4em .3em 0;transform:none !important;opacity:1 !important}
  .hero-orbit{height:auto;aspect-ratio:auto;padding:4px 0}
  .hero-orbit__glow,.hero-orbit__ring,.hero-orbit__core{display:none}
}
