/* research.jsx — spintronics page */

const { useState: useStateR, useEffect: useEffectR, useRef: useRefR } = React;

// SpinText — wraps a string into per-character <span>s that the
// global controller can rotate. Word boundaries are preserved so
// line-breaking still happens between words.
function SpinText({ children }) {
  const text = typeof children === "string" ? children : String(children ?? "");
  const parts = text.split(/(\s+)/);
  return (
    <>
      {parts.map((w, wi) => {
        if (!w) return null;
        if (/^\s+$/.test(w)) return <React.Fragment key={wi}>{w}</React.Fragment>;
        return (
          <span key={wi} style={{ display: "inline-block", whiteSpace: "nowrap" }}>
            {Array.from(w).map((ch, ci) => (
              <span
                key={ci}
                data-spin-char=""
                style={{ display: "inline-block", willChange: "transform" }}
              >
                {ch}
              </span>
            ))}
          </span>
        );
      })}
    </>
  );
}

// Cursor (or finger) as a local magnetic field — rotates nearby
// [data-spin-char] elements tangentially, then lerps them back to
// rest. Works on touch: pointermove fires for both mouse and touch,
// and pointerup/cancel deactivates only for touch so the finger
// "lifting" lets glyphs relax while a real mouse keeps interacting.
function SpinFieldController() {
  useEffectR(() => {
    const reduce = window.matchMedia &&
      window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (reduce) return;

    const cursor = { x: -9999, y: -9999, active: false };
    const onMove = (e) => {
      cursor.x = e.clientX;
      cursor.y = e.clientY;
      cursor.active = true;
    };
    const onMouseLeave = () => { cursor.active = false; };
    const onPointerEnd = (e) => {
      if (e.pointerType === "touch" || e.pointerType === "pen") {
        cursor.active = false;
      }
    };
    window.addEventListener("pointermove", onMove, { passive: true });
    window.addEventListener("pointerleave", onMouseLeave);
    window.addEventListener("pointerup", onPointerEnd, { passive: true });
    window.addEventListener("pointercancel", onPointerEnd, { passive: true });

    const radius = 90;
    const radius2 = radius * radius;
    const maxAmp = (35 * Math.PI) / 180;
    const angles = new WeakMap();
    // Tracks how many elements still have a non-resting angle so we
    // can skip the whole walk when the field is idle.
    let dirtyCount = 0;
    let raf = 0;

    const tick = () => {
      // Idle short-circuit: cursor is parked AND every glyph is at rest.
      if (!cursor.active && dirtyCount === 0) {
        raf = requestAnimationFrame(tick);
        return;
      }
      const els = document.querySelectorAll("[data-spin-char]");
      const vh = window.innerHeight;
      let nextDirty = 0;
      els.forEach((el) => {
        const r = el.getBoundingClientRect();
        if (r.bottom < -50 || r.top > vh + 50) {
          if (angles.get(el)) {
            el.style.transform = "";
            angles.set(el, 0);
          }
          return;
        }
        const ex = r.left + r.width / 2;
        const ey = r.top + r.height / 2;
        let target = 0;
        if (cursor.active) {
          const dx = ex - cursor.x;
          const dy = ey - cursor.y;
          const d2 = dx * dx + dy * dy;
          if (d2 < radius2) {
            const d = Math.sqrt(d2);
            const f = 1 - d / radius;
            let ang = Math.atan2(dy, dx) + Math.PI / 2;
            while (ang > Math.PI) ang -= 2 * Math.PI;
            while (ang < -Math.PI) ang += 2 * Math.PI;
            target = Math.max(-maxAmp, Math.min(maxAmp, ang * f));
          }
        }
        let cur = angles.get(el) || 0;
        cur += (target - cur) * 0.18;
        angles.set(el, cur);
        if (Math.abs(cur) < 0.002) {
          if (el.style.transform) el.style.transform = "";
        } else {
          el.style.transform = `rotate(${((cur * 180) / Math.PI).toFixed(2)}deg)`;
          nextDirty++;
        }
      });
      dirtyCount = nextDirty;
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);

    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener("pointermove", onMove);
      window.removeEventListener("pointerleave", onMouseLeave);
      window.removeEventListener("pointerup", onPointerEnd);
      window.removeEventListener("pointercancel", onPointerEnd);
    };
  }, []);
  return null;
}

function Research() {
  useLang();

  const papers = [
    {
      n: "01",
      year: "2025—",
      title: "Investigation of Domain-wall Mass & Inertia Effects near the Angular Momentum Compensation Temperature in Ferrimagnets",
      authors: "Ultrafast Spin Dynamics Lab · Prof. Kab-jin Kim · KAIST",
      venue: "in progress · lab intern, sole-investigator track",
      method: "experimental + mumax3",
      lab: {
        name: "Ultrafast Spin Dynamics Laboratory",
        pi_en: "Prof. Kab-jin Kim",
        pi_kr: "김갑진 교수",
        url: "https://spintronics.kaist.ac.kr/",
        blurb_en: "Observes and interprets spin dynamics in magnetic materials, with applications to spintronic memory and logic devices.",
        blurb_kr: "자성체 내 스핀 동역학을 관측·해석하고, 이를 스핀트로닉 메모리·로직 소자 개발에 응용한다.",
      },
    },
    {
      n: "02",
      year: "2023—24",
      title: "Higher-order Phase-locking Phenomenon in a Domain Wall",
      authors: "Quantum Spin Dynamics Lab · Prof. Se-Kwon Kim · KAIST",
      venue: "undergraduate research, sole-investigator track",
      method: "mumax3, Python",
      lab: {
        name: "Quantum Spin Dynamics Laboratory",
        pi_en: "Prof. Se-Kwon Kim",
        pi_kr: "김세권 교수",
        url: "https://sites.google.com/site/sekwonkimphysics",
        blurb_en: "A condensed-matter theory group focused on quantum spin dynamics — fundamental physics of magnetism and superconductivity, and their applications to spintronics and neuromorphic computing.",
        blurb_kr: "양자 스핀 동역학에 초점을 둔 응집물리 이론 그룹. 자성·초전도의 근본 물리와 그 스핀트로닉스·뉴로모픽 응용을 연구한다.",
      },
    },
    {
      n: "03",
      year: "2025—",
      title: "Korean edition · Spintronics (Junichiro Inoue & Itoh Hiroyoshi)",
      authors: "translation review",
      venue: "in progress",
      method: "review of Korean translation",
      note_en: "Review of the Korean edition of Inoue & Itoh's Spintronics — terminology, conventions, and pedagogical clarity.",
      note_kr: "이노우에 & 이토 『스핀트로닉스』 한국어판 번역 검토 — 용어·표기·교육적 명료성 중심.",
    },
  ];

  return (
    <div className="page" style={{ paddingTop: 140 }}>
      <SpinFieldController />
      <div style={{ position: "relative", zIndex: 1 }}>
      <div className="page-eyebrow">
        <span className="micro">{t("Index")} 02</span>
        <span style={{ width: 24, height: 1, background: "var(--fg)" }} />
        <span className="micro micro-fg">{t("Research · Spintronics")}</span>
      </div>

      <div className="responsive-stack" style={{ display: "grid", gridTemplateColumns: "1fr 2fr", gap: 64, marginBottom: 80, alignItems: "end" }}>
        <div>
          <div className="micro" style={{ marginBottom: 12 }}>{t("arXiv-style abstract")}</div>
          <div className="micro" style={{ color: "var(--fg-muted)" }}>{t("2 labs · 2023–present")}</div>
        </div>
        <h1 className="display-lg" style={{ color: "rgba(0,0,0,0.22)" }}>
          {window.__lang === "kr" ? (
            <>
              <SpinText>{"매질이 허락하는 속도보다 "}</SpinText>
              <span style={{ color: "var(--fg)" }}><SpinText>{"더 빨리"}</SpinText></span>
              <SpinText>{" 정보를 옮기는 "}</SpinText>
              <span style={{ color: "var(--fg)" }}><SpinText>{"스핀 텍스처"}</SpinText></span>
              <SpinText>{". 페리자성 도메인 월의 "}</SpinText>
              <span style={{ color: "var(--fg)" }}><SpinText>{"질량·관성"}</SpinText></span>
              <SpinText>{", 그리고 거기서 "}</SpinText>
              <span style={{ color: "var(--fg)" }}><SpinText>{"뉴로모픽 하드웨어"}</SpinText></span>
              <SpinText>{"로 이어지는 긴 길."}</SpinText>
            </>
          ) : (
            <>
              <span style={{ color: "var(--fg)" }}><SpinText>{"Spin textures"}</SpinText></span>
              <SpinText>{" that move information "}</SpinText>
              <span style={{ color: "var(--fg)" }}><SpinText>{"faster than the medium"}</SpinText></span>
              <SpinText>{" that carries them. "}</SpinText>
              <span style={{ color: "var(--fg)" }}><SpinText>{"Ferrimagnetic domain-wall mass and inertia"}</SpinText></span>
              <SpinText>{" — and the long path from there to "}</SpinText>
              <span style={{ color: "var(--fg)" }}><SpinText>{"neuromorphic hardware"}</SpinText></span>
              <SpinText>{"."}</SpinText>
            </>
          )}
        </h1>
      </div>

      {/* Abstract block */}
      <div className="responsive-stack" style={{
        border: "1px solid var(--line)", padding: 32, marginBottom: 100,
        display: "grid", gridTemplateColumns: "180px 1fr", gap: 32,
      }}>
        <div>
          <div className="micro" style={{ marginBottom: 12 }}>{t("Abstract")}</div>
          <div className="micro" style={{ color: "var(--fg-muted)", marginBottom: 4 }}>{t("PI")}</div>
          <div className="body-sm" style={{ marginBottom: 12 }}>{window.__lang === "kr" ? "김갑진 교수" : "Prof. Kab-jin Kim"}<br/><span style={{ color: "var(--fg-muted)" }}>{t("Ultrafast Spin Dynamics Lab")}</span></div>
          <div className="micro" style={{ color: "var(--fg-muted)", marginBottom: 4 }}>{t("Prior PI")}</div>
          <div className="body-sm">{window.__lang === "kr" ? "김세권 교수" : "Prof. Se-Kwon Kim"}<br/><span style={{ color: "var(--fg-muted)" }}>{t("Quantum Spin Dynamics Lab")}</span></div>
        </div>
        <div className="body-lg" style={{ fontFamily: "var(--font-mono)", fontSize: 14, lineHeight: 1.7 }}>
          {window.__lang === "kr" ? (
            <>각운동량 보상 온도 T<sub>A</sub> 부근에서 페리자성(FiM) 도메인 월(DW)이 어떻게 움직이는지를 본다. 이 온도에선 알짜 스핀 밀도가 0이 되는데, 알짜 자화는 그대로 남는다. Landau–Lifshitz–Bloch 틀에 마이크로마그네틱 시뮬레이션(mumax3)을 얹어, 펨토초 광 펄스 아래 도메인 월 속도를 서브피코초까지 분해하고, 세차 운동 영역을 유효 1차원 라그랑지안 위에 옮긴다. 예비 데이터에서, 순수 강자성체엔 없던 비단조 v(α) 곡선이 잡힌다. 보상 조건이 위치를 옮긴 Walker형 붕괴로 본다.</>
          ) : (
            <>We investigate the dynamics of ferrimagnetic (FiM) domain walls (DW) near the angular-momentum compensation temperature T<sub>A</sub>, where the net spin density vanishes while the net magnetization remains finite. Using micromagnetic simulations (mumax3) coupled to a Landau-Lifshitz-Bloch framework, we resolve sub-picosecond DW velocities under femtosecond optical pulses and map the precessional regime onto an effective 1D Lagrangian. Preliminary data suggest a non-monotonic v(α) characteristic absent in pure ferromagnets — a signature we attribute to a Walker-like breakdown shifted by the compensation condition.</>
          )}
        </div>
      </div>

      {/* Papers list */}
      <div style={{ marginBottom: 120 }}>
        <div className="micro" style={{ marginBottom: 32 }}>{t("Selected work / publications")}</div>
        {papers.map((p, i) => (
          <PaperRow key={i} paper={p} />
        ))}
      </div>

      <div className="responsive-stack" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 48, marginBottom: 48 }}>
        <div style={{ border: "1px solid var(--line)", padding: 32 }}>
          <div className="micro" style={{ marginBottom: 12 }}>{t("Tooling")}</div>
          <div className="display-md" style={{ marginBottom: 16 }}>{t("mumax3 · Python · Mathematica · CUDA")}</div>
          <div className="body" style={{ color: "var(--fg-muted)" }}>
            {t("Most simulations run on a small in-house GPU cluster. ML-based fitting of velocity curves is in progress.")}
          </div>
        </div>
        <div style={{ border: "1px solid var(--line)", padding: 32 }}>
          <div className="micro" style={{ marginBottom: 12 }}>{t("Other affiliations")}</div>
          <div className="body" style={{ marginBottom: 8 }}>{t("· Department Representative, KAIST Physics (2023–24)")}</div>
          <div className="body" style={{ marginBottom: 8 }}>{t("· Student Ambassador (KAINURI), KAIST Physics (2022–24)")}</div>
          <div className="body" style={{ color: "var(--fg-muted)" }}>{t("· National S&T Scholarship · Korea Student Aid Foundation, 2022")}</div>
        </div>
      </div>

      {/* Long-horizon: spintronics → neuromorphic */}
      <div style={{
        border: "1px solid var(--fg)", padding: 32, marginBottom: 80,
        background: "var(--fg)", color: "var(--bg)",
        display: "grid", gridTemplateColumns: "180px 1fr", gap: 32,
      }} className="responsive-stack">
        <div>
          <div className="micro" style={{ marginBottom: 12, color: "rgba(255,255,255,0.55)" }}>{t("Long horizon")}</div>
          <div className="micro" style={{ color: "rgba(255,255,255,0.55)" }}>{t("Spintronics → Neuromorphic")}</div>
        </div>
        <div>
          <div className="display-md" style={{ marginBottom: 16, color: "var(--bg)" }}>
            <SpinText>{t("Domain-wall motion as a synapse. Ferrimagnet compensation as a low-power switching regime.")}</SpinText>
          </div>
          <div className="body" style={{ color: "rgba(255,255,255,0.78)" }}>
            {t("Pinning and propagation of a domain wall physically mimic synaptic weight updates; the dynamics near angular-momentum compensation in ferrimagnets sit in a low-power switching regime that is directly relevant to neuromorphic circuits. The eventual digital twin of an individual is, on this view, the same problem as building neuromorphic hardware — and that is the bridge the rest of the work is being prepared to cross.")}
          </div>
        </div>
      </div>
      </div>
    </div>
  );
}

function PaperRow({ paper }) {
  useLang();
  const [hover, setHover] = useStateR(false);
  const [open, setOpen] = useStateR(false);
  const isKr = window.__lang === "kr";

  // Hover-bg toggle only on devices that actually have hover. Touch
  // taps fire mouseenter without a matching mouseleave, so without
  // this gate the row would stay inverted after a tap-to-expand.
  const canHover = useRefR(
    typeof window !== "undefined" &&
      window.matchMedia &&
      window.matchMedia("(hover: hover)").matches
  );
  const enterHover = () => { if (canHover.current) setHover(true); };
  const leaveHover = () => { if (canHover.current) setHover(false); };

  return (
    <div style={{ borderTop: "1px solid var(--line-soft)" }}>
      <div
        onClick={() => setOpen((v) => !v)}
        onMouseEnter={enterHover}
        onMouseLeave={leaveHover}
        data-cursor="link"
        data-cursor-label={open ? t("Close") : t("Open")}
        className="paper-row"
        style={{
          display: "grid",
          gridTemplateColumns: "60px 80px 1fr 200px 60px",
          gap: 24,
          alignItems: "baseline",
          cursor: "none",
          position: "relative",
          background: hover ? "var(--fg)" : "transparent",
          color: hover ? "var(--bg)" : "var(--fg)",
          margin: hover ? "0 -24px" : "0",
          padding: hover ? "24px" : "24px 0",
          transition: "all 300ms var(--easing-default)",
        }}
      >
        <span className="micro pr-n" style={{ color: hover ? "var(--bg)" : "var(--fg-muted)" }}>{paper.n}</span>
        <span className="micro pr-year">{paper.year}</span>
        <div className="pr-title">
          <div className="display-md" style={{ marginBottom: 6, fontSize: "clamp(20px, 2vw, 28px)" }}>
            <SpinText>{t(paper.title)}</SpinText>
          </div>
          <div className="body-sm" style={{ color: hover ? "rgba(255,255,255,0.7)" : "var(--fg-muted)" }}>{t(paper.authors)}</div>
        </div>
        <div className="pr-venue">
          <div className="body-sm" style={{ marginBottom: 4 }}>{t(paper.venue)}</div>
          <div className="micro" style={{ color: hover ? "rgba(255,255,255,0.5)" : "var(--fg-muted)" }}>{t(paper.method)}</div>
        </div>
        <span className="pr-arrow" style={{
          fontFamily: "var(--font-mono)", fontSize: 16,
          transform: open ? "rotate(90deg)" : (hover ? "translateX(8px)" : "translateX(0)"),
          transition: "transform 300ms var(--easing-default)",
        }}>→</span>
      </div>

      <div style={{
        display: "grid",
        gridTemplateRows: open ? "1fr" : "0fr",
        transition: "grid-template-rows 320ms var(--easing-default)",
      }}>
        <div style={{ overflow: "hidden" }}>
          {paper.lab ? (
            <div style={{
              padding: "20px 0 36px",
              display: "grid",
              gridTemplateColumns: "180px 1fr 220px",
              gap: 32,
              alignItems: "start",
            }} className="responsive-stack">
              <div>
                <div className="micro" style={{ marginBottom: 8, color: "var(--fg-muted)" }}>{t("Lab")}</div>
                <div className="body-sm" style={{ marginBottom: 4 }}>{t(paper.lab.name)}</div>
                <div className="micro" style={{ color: "var(--fg-muted)" }}>{isKr ? paper.lab.pi_kr : paper.lab.pi_en}</div>
              </div>
              <div className="body" style={{ color: "var(--fg-muted)", lineHeight: 1.65 }}>
                {isKr ? paper.lab.blurb_kr : paper.lab.blurb_en}
              </div>
              <a
                href={paper.lab.url}
                target="_blank"
                rel="noopener noreferrer"
                data-cursor="link"
                data-cursor-label={t("Open")}
                onClick={(e) => e.stopPropagation()}
                className="micro"
                style={{
                  fontFamily: "var(--font-mono)",
                  textDecoration: "underline",
                  cursor: "none",
                  alignSelf: "start",
                  wordBreak: "break-all",
                }}
              >
                {paper.lab.url.replace(/^https?:\/\//, "").replace(/\/$/, "")} ↗
              </a>
            </div>
          ) : paper.note_en ? (
            <div style={{ padding: "20px 0 36px", color: "var(--fg-muted)", maxWidth: 720 }} className="body">
              {isKr ? paper.note_kr : paper.note_en}
            </div>
          ) : null}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Research });
