// Creative — DEVA, a vinyl LP.
// Front cover (DEVA mark) → click → back cover (tracklist A1/A2/B1/B2)
//                         → click track → liner notes for that pillar.
// Persistent spinning vinyl + crackle toggle in the corner.

const { useState: useStateCr, useRef: useRefCr, useEffect: useEffectCr } = React;

const TRACKS = {
  a1: {
    side: "A", num: "A1", title: "Music", credit: "Piano, Guitar",
    sub: "PIANO (CLASSICAL + IMPROVISATION) · GUITAR",
    body: "Recordings forthcoming. Piano sits closer to classical and improvisation; guitar is its own ongoing study. Embeds and waveforms drop in here as the tape gets cut.",
  },
  a2: {
    side: "A", num: "A2", title: "Writing & Research", credit: "Essays, primary-source equity work",
    sub: "CATALOG OF ESSAYS AND EQUITY WRITE-UPS",
    body: "Field notes on agentic engineering, AI, and quantitative finance. Live at /blog and growing. No fabrications, no filler.",
  },
  b1: {
    side: "B", num: "B1", title: "Market Commentary", credit: "Notes from the tape",
    sub: "RUNNING COLUMN OF SHORT OBSERVATIONS",
    body: "Short notes from watching markets. Formatted like a critic's column — single thought per entry, dated, sometimes wrong.",
  },
  b2: {
    side: "B", num: "B2", title: "Live", credit: "Speaking, podcasts (forthcoming)",
    sub: "TALKS · PODCAST APPEARANCES",
    body: "Nothing pressed here yet. Space held for forthcoming speaking and podcast appearances. No entries to fabricate — this stays empty until it isn't.",
  },
};

// Seed content per pillar — honest, sparse where I have nothing
const A2_ESSAYS = [
  { date: "2026.05", title: "Agentic engineering patterns I actually use", abs: "Context budgets, tool design, planner-executor splits, eval harnesses. The handful of patterns that survive contact with production.", href: "/blog/agentic-engineering-patterns" },
  { date: "2026.05", title: "LLM agents in quantitative finance", abs: "Forensic accounting, DCF assembly, and thesis generation. Where the agent loop earns its keep, and where it still gets you killed.", href: "/blog/llm-agents-in-quantitative-finance" },
  { date: "2026.05", title: "Frontier AI in 2026: what actually changed", abs: "Long context, agentic capability, open weights, model routing. The four shifts that reset how I build.", href: "/blog/frontier-ai-2026-what-actually-changed" },
  { date: "2026.03", title: "LVT.MEMO.001 — Why I'm building Leviathan", abs: "Origin essay on the case for autonomous equity research." },
  { date: "2026.04", title: "LVT.MEMO.002 — DCF, agent-assembled", abs: "How the WACC → DCF → bear/base/bull pipeline is constructed end-to-end." },
];

const B1_NOTES = []; // honest empty state
const B2_LIVE  = []; // honest empty state

window.TRACKS = TRACKS;
window.A2_ESSAYS = A2_ESSAYS;
window.B1_NOTES = B1_NOTES;
window.B2_LIVE = B2_LIVE;

function Creative({ initialDetail, onNavigate, fromHome }) {
  const [view, setView] = useStateCr(initialDetail || "front");
  const [hoveringSleeve, setHoveringSleeve] = useStateCr(false);
  const [tilt, setTilt] = useStateCr({ x: 0, y: 0 });
  const [crackle, setCrackle] = useStateCr(false);

  useEffectCr(() => { setView(initialDetail || "front"); }, [initialDetail]);

  const go = (next) => {
    setView(next);
    onNavigate({ world: "creative", detail: next === "front" ? null : next });
  };

  const onMouseMoveSleeve = (e) => {
    if (view !== "front") return;
    const r = e.currentTarget.getBoundingClientRect();
    const px = ((e.clientX - r.left) / r.width - 0.5) * 2;  // -1..1
    const py = ((e.clientY - r.top)  / r.height - 0.5) * 2;
    setTilt({ x: py * -10, y: px * 14 });
  };
  const resetTilt = () => setTilt({ x: 0, y: 0 });

  return (
    <div className={`world-enter ${fromHome ? "entry-fresh" : ""}`} data-world="creative" style={crStyles.root}>
      {/* Entry-only flourish: vinyl record slides out from behind the sleeve */}
      {fromHome && <div data-anim="vinyl-pull" />}

      <div style={crStyles.bg} />

      {/* header */}
      <header style={crStyles.header}>
        <div>
          <div className="mono" style={crStyles.kicker}>
            // WORLD 03 — CREATIVE
          </div>
          <h1 style={crStyles.h1}>DEVA — the catalog</h1>
          <p style={crStyles.lede}>
            One brand. One sleeve. Four pillars on the back: Music, Writing &amp; Research, Market Commentary, Live.
          </p>
        </div>
        <div style={crStyles.titlePlate}>
          <PlateField label="CATALOG" value="DEVA-001" />
          <PlateField label="FORMAT"  value='12" LP · ongoing' />
          <PlateField label="VIEW"    value={view.toUpperCase()} />
        </div>
      </header>

      {/* main stage */}
      <div style={crStyles.stage}>
        {/* breadcrumb in the LP world */}
        <div style={crStyles.crumbs}>
          <CrumbBtn active={view === "front"} onClick={() => go("front")}>FRONT</CrumbBtn>
          <span style={{ color: "var(--dim)" }}>·</span>
          <CrumbBtn active={view === "back"} onClick={() => go("back")}>BACK</CrumbBtn>
          {TRACKS[view] ? (
            <>
              <span style={{ color: "var(--dim)" }}>·</span>
              <CrumbBtn active onClick={() => {}}>
                {view.toUpperCase()} · {TRACKS[view].title.toUpperCase()}
              </CrumbBtn>
            </>
          ) : null}
        </div>

        {/* Sleeve area — 3D flip container */}
        <div
          className="creative-sleeve-area"
          style={crStyles.sleeveArea}
          onMouseEnter={() => setHoveringSleeve(true)}
          onMouseLeave={() => { setHoveringSleeve(false); resetTilt(); }}
          onMouseMove={onMouseMoveSleeve}
        >
          {view === "front" || view === "back" ? (
            <div style={{
              ...crStyles.sleeve3d,
              transform: `rotateX(${tilt.x * 0.7}deg) rotateY(${(view === "back" ? 180 : 0) + tilt.y * 0.7}deg) translateZ(0)`,
            }}>
              {/* FRONT */}
              <FrontCover hovering={hoveringSleeve && view === "front"} onClick={() => view === "front" && go("back")} />
              {/* BACK */}
              <BackCover onPickTrack={(k) => go(k)} />
            </div>
          ) : (
            <LinerNotes track={TRACKS[view]} viewKey={view} onClose={() => go("back")} />
          )}
        </div>
      </div>

      {/* persistent spinning vinyl + crackle toggle */}
      <div className="creative-persistent" style={crStyles.persistent}>
        <SpinningVinyl />
        <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
          <div className="mono" style={{ fontSize: 9, letterSpacing: ".22em", color: "var(--muted)" }}>NOW PLAYING</div>
          <div style={{ fontFamily: "var(--serif)", fontStyle: "italic", fontSize: 17, lineHeight: 1.2, color: "var(--fg)" }}>
            {view === "front" || view === "back" ? "DEVA — long-player" : `${TRACKS[view].num} · ${TRACKS[view].title}`}
          </div>
          <button onClick={() => setCrackle((c) => !c)} className="mono" style={{
            ...crStyles.crackleBtn,
            color: crackle ? "var(--amber)" : "var(--muted)",
            borderColor: crackle ? "var(--amber)" : "var(--line-2)",
          }}>
            <span style={{ marginRight: 6 }}>{crackle ? "●" : "○"}</span>
            {crackle ? "CRACKLE ON" : "CRACKLE OFF"}
          </button>
        </div>
      </div>

      {crackle && <div style={crStyles.crackleOverlay} />}
    </div>
  );
}

// ---- subcomponents -------------------------------------------------------

function FrontCover({ hovering, onClick }) {
  return (
    <div style={crStyles.face} onClick={onClick}>
      <div style={crStyles.coverFront}>
        <div style={crStyles.coverHairline} />
        <div style={{ flex: 1, display: "flex", alignItems: "center", justifyContent: "center", flexDirection: "column" }}>
          <h2 style={crStyles.brandMark}>DEVA</h2>
          <div className="mono" style={crStyles.brandTag}>LONG-PLAYER · ONGOING</div>
        </div>
        {/* corner technicals */}
        <div style={crStyles.coverFootRow}>
          <span className="mono" style={crStyles.coverFootText}>DEVA-001 / SIDE A · B</span>
          <span className="mono" style={crStyles.coverFootText}>33⅓ RPM</span>
        </div>

        {/* spine ghost peeking on hover */}
        <div style={{
          ...crStyles.spine,
          opacity: hovering ? 1 : 0,
          transform: hovering ? "translateX(0)" : "translateX(-12px)",
        }}>
          <span className="mono" style={crStyles.spineText}>DEVA — LONG-PLAYER · DEVA-001 · 2026 · SIDE A / SIDE B</span>
        </div>

        <div style={{ ...crStyles.cornerBracket, top: 18, left: 18, borderLeft: "1px solid var(--fg-2)", borderTop: "1px solid var(--fg-2)" }} />
        <div style={{ ...crStyles.cornerBracket, top: 18, right: 18, borderRight: "1px solid var(--fg-2)", borderTop: "1px solid var(--fg-2)" }} />
        <div style={{ ...crStyles.cornerBracket, bottom: 18, left: 18, borderLeft: "1px solid var(--fg-2)", borderBottom: "1px solid var(--fg-2)" }} />
        <div style={{ ...crStyles.cornerBracket, bottom: 18, right: 18, borderRight: "1px solid var(--fg-2)", borderBottom: "1px solid var(--fg-2)" }} />
      </div>
    </div>
  );
}

function BackCover({ onPickTrack }) {
  return (
    <div style={{ ...crStyles.face, transform: "rotateY(180deg) translateZ(2px)" }}>
      <div style={crStyles.coverBack}>
        <div style={crStyles.backHeader}>
          <div>
            <div className="mono" style={{ fontSize: 11, letterSpacing: ".24em", color: "oklch(28% 0.02 50)" }}>DEVA-001 · BACK COVER</div>
            <div style={{ fontFamily: "var(--serif)", fontStyle: "italic", fontSize: 38, marginTop: 6, color: "oklch(12% 0.02 50)", lineHeight: 1 }}>
              Tracklist
            </div>
          </div>
          <div className="mono" style={{ fontSize: 12, letterSpacing: ".22em", color: "oklch(35% 0.05 30)", fontWeight: 600 }}>
            33⅓ RPM · STEREO
          </div>
        </div>

        <hr style={crStyles.backHr} />

        {/* SIDE A */}
        <div style={crStyles.sideBlock}>
          <div className="mono" style={crStyles.sideLabel}>SIDE A</div>
          <Track id="a1" onClick={() => onPickTrack("a1")} />
          <Track id="a2" onClick={() => onPickTrack("a2")} />
        </div>

        {/* SIDE B */}
        <div style={crStyles.sideBlock}>
          <div className="mono" style={crStyles.sideLabel}>SIDE B</div>
          <Track id="b1" onClick={() => onPickTrack("b1")} />
          <Track id="b2" onClick={() => onPickTrack("b2")} />
        </div>

        <hr style={crStyles.backHr} />

        <div style={crStyles.backFoot}>
          <span className="mono" style={crStyles.coverFootText}>℗ © DEVA · ALL CUTS BY A. DEVA</span>
          <span className="mono" style={crStyles.coverFootText}>PRINTED IN NJ · 2026</span>
        </div>
      </div>
    </div>
  );
}

function Track({ id, onClick }) {
  const t = TRACKS[id];
  const dots = "·".repeat(80);
  return (
    <button onClick={onClick} className="mono" style={crStyles.trackRow}>
      <span style={crStyles.trackNum}>{t.num}.</span>
      <span style={{ ...crStyles.trackTitle, flexShrink: 0 }}>{t.title}</span>
      <span style={{ ...crStyles.trackDots, flex: 1, minWidth: 0, overflow: "hidden", whiteSpace: "nowrap" }} aria-hidden>{dots}</span>
      <span style={{ ...crStyles.trackCredit, flexShrink: 0 }}>{t.credit}</span>
      <span style={crStyles.trackArrow}>▸</span>
    </button>
  );
}

function LinerNotes({ track, viewKey, onClose }) {
  return (
    <div style={crStyles.linerRoot}>
      {/* "inner sleeve" emerging from the jacket */}
      <div style={crStyles.linerSleeve} key={viewKey}>
        <div style={crStyles.linerHeader}>
          <div>
            <div className="mono" style={{ fontSize: 10, letterSpacing: ".22em", color: "var(--muted)" }}>
              SIDE {track.side} · {track.num} · LINER NOTES
            </div>
            <h2 style={crStyles.linerTitle}>{track.title}</h2>
            <div className="mono" style={{ color: "var(--amber)", fontSize: 11, letterSpacing: ".22em" }}>{track.sub}</div>
          </div>
          <button onClick={onClose} className="mono" style={crStyles.linerClose}>← BACK COVER</button>
        </div>

        <p style={crStyles.linerBlurb}>{track.body}</p>

        <hr style={{ border: 0, borderTop: "1px dashed var(--line-2)", margin: "20px 0" }} />

        <div style={crStyles.linerBody}>
          {viewKey === "a1" && <A1Music />}
          {viewKey === "a2" && <A2Writing />}
          {viewKey === "b1" && <B1Commentary />}
          {viewKey === "b2" && <B2Live />}
        </div>
      </div>
    </div>
  );
}

// ---- pillar bodies --------------------------------------------------------

function A1Music() {
  return (
    <div style={{ display: "grid", gap: 18 }}>
      <Waveform label="PIANO · improv sketch — placeholder" />
      <Waveform label="GUITAR · finger-picked study — placeholder" />
      <div className="mono" style={{ color: "var(--muted)", fontSize: 11, letterSpacing: ".18em" }}>
        — RECORDINGS FORTHCOMING
      </div>
    </div>
  );
}

function Waveform({ label }) {
  // simple placeholder bars
  const bars = Array.from({ length: 80 }).map((_, i) => Math.sin(i * 0.27) * 0.5 + 0.5 + Math.random() * 0.25);
  return (
    <div style={{ padding: "14px 16px", border: "1px solid var(--line)", background: "oklch(13% 0.014 60 / 0.7)" }}>
      <div className="mono" style={{ fontSize: 10, letterSpacing: ".22em", color: "var(--muted)", marginBottom: 8 }}>{label}</div>
      <div style={{ display: "flex", alignItems: "center", height: 64, gap: 2 }}>
        {bars.map((v, i) => (
          <span key={i} style={{
            display: "inline-block",
            width: "1.5%", height: `${Math.max(8, v * 100)}%`,
            background: "var(--amber)", opacity: 0.55,
          }} />
        ))}
      </div>
      <div style={{ display: "flex", justifyContent: "space-between", marginTop: 6 }}>
        <span className="mono" style={{ fontSize: 10, color: "var(--dim)" }}>00:00</span>
        <span className="mono" style={{ fontSize: 10, color: "var(--dim)" }}>— : —</span>
      </div>
    </div>
  );
}

function A2Writing() {
  const recent = [...A2_ESSAYS]
    .sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0))
    .slice(0, 3);
  return (
    <div style={{ display: "grid", gap: 12 }}>
      {recent.map((e, i) => {
        const inner = (
          <>
            <span className="mono" style={{ color: "var(--amber)", fontSize: 11, letterSpacing: ".22em", minWidth: 80 }}>{e.date}</span>
            <div style={{ flex: 1 }}>
              <div style={{ fontFamily: "var(--serif)", fontSize: 19, fontStyle: "italic", color: "var(--fg)" }}>
                {e.title}
                {e.href && (
                  <span className="mono" style={{ marginLeft: 10, fontSize: 10, color: "var(--amber)", letterSpacing: ".22em", verticalAlign: "middle" }}>
                    READ →
                  </span>
                )}
              </div>
              <div className="mono" style={{ marginTop: 4, fontSize: 12, color: "var(--fg-2)", letterSpacing: ".02em" }}>{e.abs}</div>
            </div>
          </>
        );
        return e.href ? (
          <a key={i} href={e.href} style={{ ...crStyles.essayRow, textDecoration: "none", cursor: "pointer" }}>
            {inner}
          </a>
        ) : (
          <div key={i} style={crStyles.essayRow}>{inner}</div>
        );
      })}
      <a
        href="/blog"
        className="mono"
        style={{ color: "var(--amber)", fontSize: 11, letterSpacing: ".22em", marginTop: 4, textDecoration: "none" }}
      >
        ALL NOTES — /BLOG →
      </a>
      <HomeBlogPointer />
    </div>
  );
}

function HomeBlogPointer() {
  const canvasRef = React.useRef(null);
  const hostRef = React.useRef(null);
  const [hover, setHover] = React.useState(false);

  React.useEffect(() => {
    const canvas = canvasRef.current;
    const host = hostRef.current;
    if (!canvas || !host) return;
    const gl = canvas.getContext("webgl", { antialias: true, alpha: true });
    if (!gl) return;

    const resize = () => {
      const r = host.getBoundingClientRect();
      const dpr = Math.min(window.devicePixelRatio || 1, 2);
      canvas.width = Math.max(1, Math.floor(r.width * dpr));
      canvas.height = Math.max(1, Math.floor(r.height * dpr));
      canvas.style.width = r.width + "px";
      canvas.style.height = r.height + "px";
      gl.viewport(0, 0, canvas.width, canvas.height);
    };
    resize();
    window.addEventListener("resize", resize);

    const vsrc = `
      attribute vec2 a_pos;
      varying vec2 v_uv;
      void main() { v_uv = (a_pos + 1.0) * 0.5; gl_Position = vec4(a_pos, 0.0, 1.0); }
    `;
    const fsrc = `
      precision mediump float;
      varying vec2 v_uv;
      uniform float u_time;
      uniform vec2 u_mouse;
      uniform float u_hover;
      float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); }
      float noise(vec2 p) {
        vec2 i = floor(p), f = fract(p);
        float a = hash(i), b = hash(i + vec2(1.0, 0.0));
        float c = hash(i + vec2(0.0, 1.0)), d = hash(i + vec2(1.0, 1.0));
        vec2 u = f * f * (3.0 - 2.0 * f);
        return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
      }
      void main() {
        vec2 uv = v_uv;
        vec2 p = uv * 3.0;
        float t = u_time * 0.12;
        float n = noise(p + vec2(t, -t * 0.7));
        n = 0.55 * n + 0.45 * noise(p * 2.3 - t);
        float d = distance(uv, u_mouse);
        float glow = smoothstep(0.55, 0.0, d) * (0.35 + 0.4 * u_hover);
        vec3 amber = vec3(0.94, 0.65, 0.20);
        vec3 phos  = vec3(0.20, 0.55, 0.45);
        vec3 col = mix(phos * 0.18, amber * 0.55, n);
        col += amber * glow;
        float scan = 0.88 + 0.12 * sin(uv.y * 90.0 + u_time * 2.0);
        col *= scan;
        float vig = smoothstep(1.05, 0.35, distance(uv, vec2(0.5)));
        col *= vig;
        gl_FragColor = vec4(col, 0.92);
      }
    `;

    const compile = (type, src) => {
      const s = gl.createShader(type);
      gl.shaderSource(s, src);
      gl.compileShader(s);
      return s;
    };
    const vs = compile(gl.VERTEX_SHADER, vsrc);
    const fs = compile(gl.FRAGMENT_SHADER, fsrc);
    const prog = gl.createProgram();
    gl.attachShader(prog, vs);
    gl.attachShader(prog, fs);
    gl.linkProgram(prog);
    gl.useProgram(prog);

    const buf = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, buf);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1,-1, 1,-1, -1,1, -1,1, 1,-1, 1,1]), gl.STATIC_DRAW);
    const loc = gl.getAttribLocation(prog, "a_pos");
    gl.enableVertexAttribArray(loc);
    gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);

    const uTime = gl.getUniformLocation(prog, "u_time");
    const uMouse = gl.getUniformLocation(prog, "u_mouse");
    const uHover = gl.getUniformLocation(prog, "u_hover");

    const mouse = { x: 0.5, y: 0.5 };
    let hoverLerp = 0;
    let targetHover = 0;
    const onMove = (e) => {
      const r = host.getBoundingClientRect();
      mouse.x = (e.clientX - r.left) / r.width;
      mouse.y = 1 - (e.clientY - r.top) / r.height;
    };
    const onEnter = () => { targetHover = 1; setHover(true); };
    const onLeave = () => { targetHover = 0; setHover(false); };
    host.addEventListener("mousemove", onMove);
    host.addEventListener("mouseenter", onEnter);
    host.addEventListener("mouseleave", onLeave);

    const start = performance.now();
    let raf = 0;
    const loop = () => {
      const t = (performance.now() - start) / 1000;
      hoverLerp += (targetHover - hoverLerp) * 0.08;
      gl.uniform1f(uTime, t);
      gl.uniform2f(uMouse, mouse.x, mouse.y);
      gl.uniform1f(uHover, hoverLerp);
      gl.drawArrays(gl.TRIANGLES, 0, 6);
      raf = requestAnimationFrame(loop);
    };
    loop();

    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener("resize", resize);
      host.removeEventListener("mousemove", onMove);
      host.removeEventListener("mouseenter", onEnter);
      host.removeEventListener("mouseleave", onLeave);
      gl.deleteBuffer(buf);
      gl.deleteProgram(prog);
      gl.deleteShader(vs);
      gl.deleteShader(fs);
    };
  }, []);

  return (
    <a
      ref={hostRef}
      href="/"
      aria-label="See the blog preview on the home page"
      style={{
        position: "relative",
        display: "block",
        marginTop: 10,
        height: 72,
        border: "1px solid var(--line)",
        borderRadius: 2,
        overflow: "hidden",
        textDecoration: "none",
        background: "oklch(11% 0.012 60 / 0.55)",
        transition: "transform 180ms ease, box-shadow 180ms ease",
        transform: hover ? "scale(1.012)" : "scale(1)",
        boxShadow: hover ? "0 0 0 1px var(--amber), 0 8px 24px oklch(60% 0.16 70 / 0.18)" : "none",
      }}
    >
      <canvas ref={canvasRef} style={{ position: "absolute", inset: 0, width: "100%", height: "100%", display: "block" }} />
      <div style={{
        position: "absolute", inset: 0, display: "flex", flexDirection: "column",
        justifyContent: "center", padding: "0 14px",
        textShadow: "0 1px 2px rgba(0,0,0,0.65), 0 0 8px rgba(0,0,0,0.45)",
      }}>
        <div className="mono" style={{ fontSize: 9, letterSpacing: ".24em", color: "var(--amber)", marginBottom: 3 }}>
          // CROSSLINK
        </div>
        <div style={{ fontFamily: "var(--serif)", fontSize: 14, fontStyle: "italic", color: "var(--fg)", lineHeight: 1.25 }}>
          Look at the blog on the main home page as well.
        </div>
        <div className="mono" style={{ marginTop: 3, fontSize: 9, letterSpacing: ".22em", color: "var(--fg-2)" }}>
          HOME → /  ▸
        </div>
      </div>
    </a>
  );
}

function B1Commentary() {
  if (B1_NOTES.length === 0) {
    return (
      <EmptyState
        line="First note pressing soon."
        sub="The format will be a critic's column — one observation per entry, dated. No filler entries until there's something to say."
      />
    );
  }
  return null;
}

function B2Live() {
  if (B2_LIVE.length === 0) {
    return (
      <EmptyState
        line="No entries yet."
        sub="Speaking and podcast appearances live here when they happen. This space stays honest until there's something to list."
      />
    );
  }
  return null;
}

function EmptyState({ line, sub }) {
  return (
    <div style={{ padding: "40px 20px", textAlign: "center", border: "1px dashed var(--line-2)", background: "oklch(13% 0.014 60 / 0.5)" }}>
      <div style={{ fontFamily: "var(--serif)", fontStyle: "italic", fontSize: 24, color: "var(--fg)" }}>{line}</div>
      <p style={{ marginTop: 10, fontFamily: "var(--serif)", color: "var(--fg-2)", maxWidth: "44ch", marginLeft: "auto", marginRight: "auto", lineHeight: 1.5 }}>
        {sub}
      </p>
    </div>
  );
}

// ---- spinning vinyl widget -----------------------------------------------

function SpinningVinyl() {
  return (
    <div style={vinylStyles.wrap}>
      <div style={vinylStyles.disc}>
        <div style={vinylStyles.groove1} />
        <div style={vinylStyles.groove2} />
        <div style={vinylStyles.groove3} />
        <div style={vinylStyles.groove4} />
        <div style={vinylStyles.label}>
          <span className="mono" style={{ fontSize: 8, letterSpacing: ".22em", color: "var(--bg)" }}>DEVA</span>
          <span className="mono" style={{ fontSize: 7, color: "var(--bg-2)", marginTop: 2 }}>33⅓</span>
        </div>
        <div style={vinylStyles.center} />
      </div>
      {/* spin animation */}
      <style>{`@keyframes spin-vinyl { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }`}</style>
    </div>
  );
}

const vinylStyles = {
  wrap: { width: 96, height: 96, flexShrink: 0 },
  disc: {
    width: "100%", height: "100%",
    borderRadius: "50%",
    background: "radial-gradient(circle at 50% 50%, oklch(20% 0.012 60) 0%, oklch(10% 0.008 60) 100%)",
    position: "relative",
    animation: "spin-vinyl 6s linear infinite",
    boxShadow: "0 6px 20px oklch(0% 0 0 / 0.6), inset 0 0 0 1px oklch(40% 0.015 60 / 0.4)",
  },
  groove1: { position: "absolute", inset: 6, borderRadius: "50%", border: "1px solid oklch(28% 0.014 60)" },
  groove2: { position: "absolute", inset: 12, borderRadius: "50%", border: "1px solid oklch(26% 0.014 60)" },
  groove3: { position: "absolute", inset: 20, borderRadius: "50%", border: "1px solid oklch(24% 0.014 60)" },
  groove4: { position: "absolute", inset: 28, borderRadius: "50%", border: "1px solid oklch(22% 0.014 60)" },
  label: {
    position: "absolute", inset: 32,
    borderRadius: "50%",
    background: "radial-gradient(circle at 50% 50%, var(--amber) 0%, oklch(60% 0.10 50) 100%)",
    display: "flex", alignItems: "center", justifyContent: "center", flexDirection: "column",
  },
  center: {
    position: "absolute", top: "50%", left: "50%",
    width: 6, height: 6, marginTop: -3, marginLeft: -3,
    background: "oklch(8% 0 0)", borderRadius: "50%",
  },
};

// ---- atoms ---------------------------------------------------------------

function PlateField({ label, value }) {
  return (
    <>
      <div className="mono" style={{ fontSize: 9, letterSpacing: ".22em", color: "var(--muted)" }}>{label}</div>
      <div className="mono" style={{ fontSize: 11, letterSpacing: ".06em", color: "var(--fg)" }}>{value}</div>
    </>
  );
}

function CrumbBtn({ children, onClick, active }) {
  return (
    <button onClick={onClick} className="mono" style={{
      background: "transparent",
      border: "1px solid var(--line-2)",
      color: active ? "var(--amber)" : "var(--fg-2)",
      borderColor: active ? "var(--amber)" : "var(--line-2)",
      padding: "5px 10px",
      fontSize: 10,
      letterSpacing: ".22em",
      cursor: "pointer",
    }}>{children}</button>
  );
}

// ---- styles --------------------------------------------------------------

const crStyles = {
  root: { position: "absolute", inset: 0, overflowY: "auto", paddingBottom: 120 },
  bg: {
    position: "absolute", inset: 0, zIndex: -1,
    background:
      "radial-gradient(ellipse at 20% 0%, oklch(22% 0.02 50 / 0.6) 0%, transparent 55%)," +
      "radial-gradient(ellipse at 80% 100%, oklch(20% 0.02 40 / 0.5) 0%, transparent 55%)," +
      "linear-gradient(180deg, oklch(13% 0.012 55), oklch(11% 0.01 55))",
  },
  header: {
    padding: "44px 56px 8px",
    display: "grid", gridTemplateColumns: "1fr auto", gap: 40, alignItems: "end",
  },
  kicker: { color: "var(--phosphor)", fontSize: 11, letterSpacing: ".22em" },
  h1: { fontFamily: "var(--serif)", fontSize: "clamp(36px, 4.0vw, 50px)", fontStyle: "italic", fontWeight: 400, margin: "16px 0 10px", letterSpacing: "-0.01em", lineHeight: 1.05 },
  lede: { margin: 0, fontFamily: "var(--serif)", fontSize: "clamp(15px, 1.1vw, 17px)", lineHeight: 1.5, color: "var(--fg-2)", maxWidth: "56ch" },
  titlePlate: {
    display: "grid", gridTemplateColumns: "auto 1fr", gap: "4px 18px",
    padding: "14px 18px", border: "1px solid var(--line)", background: "oklch(13% 0.014 60 / 0.7)", minWidth: 320,
  },

  stage: {
    padding: "8px 56px calc(var(--terminal-h) + 24px)",
    display: "flex", flexDirection: "column", alignItems: "center", gap: 16,
  },
  crumbs: { display: "flex", alignItems: "center", gap: 8 },

  sleeveArea: {
    width: "min(640px, 70vw, 60vh)",
    aspectRatio: "1 / 1",
    perspective: 2000,
    perspectiveOrigin: "center",
    marginTop: 8,
  },

  sleeve3d: {
    position: "relative",
    width: "100%", height: "100%",
    transformStyle: "preserve-3d",
    transition: "transform 900ms cubic-bezier(.2, .8, .2, 1)",
    willChange: "transform",
  },

  face: {
    position: "absolute", inset: 0,
    backfaceVisibility: "hidden",
    WebkitBackfaceVisibility: "hidden",
    cursor: "pointer",
    transform: "translateZ(2px)",  // separates from back face to prevent z-fighting
    willChange: "transform",
    transformStyle: "preserve-3d",
  },

  coverFront: {
    position: "relative",
    width: "100%", height: "100%",
    background:
      "radial-gradient(ellipse at 30% 20%, oklch(18% 0.012 55) 0%, oklch(10% 0.008 55) 80%)," +
      "linear-gradient(180deg, oklch(13% 0.01 55) 0%, oklch(10% 0.008 55) 100%)",
    display: "flex", flexDirection: "column",
    boxShadow:
      "0 30px 80px oklch(0% 0 0 / 0.6), 0 8px 20px oklch(0% 0 0 / 0.5)," +
      "inset 0 0 0 1px oklch(40% 0.012 55 / 0.5)," +
      "inset 0 0 120px oklch(0% 0 0 / 0.6)",
    overflow: "hidden",
  },
  coverHairline: {
    position: "absolute", inset: 14,
    border: "1px solid oklch(60% 0.015 60 / 0.5)",
    pointerEvents: "none",
  },
  brandMark: {
    fontFamily: "var(--serif)",
    fontStyle: "italic",
    fontWeight: 400,
    fontSize: "clamp(80px, 13vw, 200px)",
    letterSpacing: "0.06em",
    margin: 0,
    color: "oklch(92% 0.014 80)",
    textShadow: "0 2px 12px oklch(0% 0 0 / 0.6)",
  },
  brandTag: {
    marginTop: 18,
    fontSize: 12,
    letterSpacing: ".42em",
    color: "var(--muted)",
  },
  coverFootRow: {
    position: "absolute",
    left: 36, right: 36, bottom: 36,
    display: "flex", justifyContent: "space-between",
  },
  coverFootText: {
    fontSize: 9, letterSpacing: ".22em", color: "var(--muted)",
  },
  spine: {
    position: "absolute", top: "50%", left: 36,
    transform: "translateY(-50%)",
    writingMode: "vertical-rl",
    transformOrigin: "left center",
    transition: "opacity 280ms ease, transform 280ms ease",
    pointerEvents: "none",
  },
  spineText: { fontSize: 10, letterSpacing: ".3em", color: "var(--amber)" },
  cornerBracket: {
    position: "absolute", width: 16, height: 16, pointerEvents: "none",
  },

  coverBack: {
    width: "100%", height: "100%",
    background:
      "radial-gradient(ellipse at 70% 0%, oklch(96% 0.008 80) 0%, oklch(92% 0.012 75) 50%, oklch(88% 0.014 70) 100%)",
    color: "oklch(15% 0.018 50)",
    padding: "48px 52px",
    display: "flex", flexDirection: "column",
    boxShadow: "0 30px 80px oklch(0% 0 0 / 0.6), inset 0 0 0 1px oklch(30% 0.02 60 / 0.3)",
    overflow: "hidden",
    // help GPU-rasterize crisp text under 3D transform
    backfaceVisibility: "hidden",
    WebkitFontSmoothing: "antialiased",
    textRendering: "geometricPrecision",
  },
  backHeader: { display: "flex", justifyContent: "space-between", alignItems: "flex-end" },
  backHr: { border: 0, borderTop: "1px solid oklch(35% 0.02 60 / 0.5)", margin: "20px 0 16px" },
  sideBlock: { marginBottom: 20 },
  sideLabel: { fontSize: 13, letterSpacing: ".24em", color: "oklch(15% 0.018 50)", marginBottom: 12, fontWeight: 700 },
  trackRow: {
    appearance: "none", background: "transparent", border: 0,
    display: "grid", gridTemplateColumns: "38px max-content 1fr max-content 22px",
    alignItems: "baseline", gap: 8,
    padding: "10px 0",
    width: "100%",
    textAlign: "left",
    color: "oklch(15% 0.018 50)",
    cursor: "pointer",
    fontSize: 17,
    fontWeight: 500,
  },
  trackNum:   { color: "var(--amber)", fontWeight: 700, fontSize: 16 },
  trackTitle: { fontWeight: 700, letterSpacing: ".06em", fontSize: 17 },
  trackDots:  { color: "oklch(30% 0.02 60 / 0.75)", overflow: "hidden", whiteSpace: "nowrap", fontSize: 15 },
  trackCredit: { fontStyle: "italic", color: "oklch(22% 0.02 50)", fontFamily: "var(--mono)", fontSize: 13 },
  trackArrow: { color: "var(--amber)", justifySelf: "end", fontSize: 16 },
  backFoot: { display: "flex", justifyContent: "space-between", marginTop: "auto" },

  // Liner notes
  linerRoot: {
    width: "100%", height: "100%",
    display: "flex", justifyContent: "center", alignItems: "stretch",
  },
  linerSleeve: {
    width: "100%", maxWidth: "min(820px, 100%)",
    padding: "32px 36px 28px",
    background:
      "linear-gradient(180deg, oklch(94% 0.01 80) 0%, oklch(90% 0.012 75) 100%)",
    color: "oklch(18% 0.018 50)",
    boxShadow: "0 30px 80px oklch(0% 0 0 / 0.6), inset 0 0 0 1px oklch(30% 0.02 60 / 0.3)",
    animation: "slideOut 600ms cubic-bezier(.2,.8,.2,1) both",
  },
  linerHeader: { display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 14 },
  linerTitle: { fontFamily: "var(--serif)", fontStyle: "italic", fontSize: 44, margin: "4px 0 6px", fontWeight: 400, color: "oklch(15% 0.02 50)" },
  linerClose: {
    appearance: "none",
    background: "transparent",
    border: "1px solid oklch(40% 0.02 60 / 0.4)",
    color: "oklch(20% 0.02 50)",
    padding: "6px 10px",
    fontSize: 10,
    letterSpacing: ".22em",
    cursor: "pointer",
  },
  linerBlurb: {
    marginTop: 18,
    fontFamily: "var(--serif)",
    fontSize: 17,
    fontStyle: "italic",
    lineHeight: 1.55,
    color: "oklch(20% 0.02 50)",
    maxWidth: "60ch",
  },
  linerBody: { color: "oklch(18% 0.018 50)" },
  essayRow: {
    display: "flex", gap: 18,
    padding: "10px 0",
    borderBottom: "1px dashed oklch(40% 0.02 60 / 0.3)",
  },

  // persistent bottom-left widget
  persistent: {
    position: "fixed",
    left: 24, bottom: 96,
    zIndex: 40,
    display: "flex", alignItems: "center", gap: 14,
    padding: "12px 16px 12px 12px",
    background: "oklch(11% 0.012 60 / 0.88)",
    border: "1px solid var(--line)",
    backdropFilter: "blur(8px)",
    WebkitBackdropFilter: "blur(8px)",
    pointerEvents: "auto",
  },
  crackleBtn: {
    appearance: "none",
    background: "transparent",
    border: "1px solid var(--line-2)",
    padding: "5px 9px",
    fontSize: 10,
    letterSpacing: ".22em",
    cursor: "pointer",
    width: "fit-content",
  },
  crackleOverlay: {
    position: "fixed", inset: 0,
    pointerEvents: "none",
    zIndex: 30,
    backgroundImage:
      "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='2.9' numOctaves='1' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.95  0 0 0 0 0.88  0 0 0 0 0.75  0 0 0 0.13 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>\")",
    opacity: 0.6,
    mixBlendMode: "screen",
    animation: "crackle 0.18s steps(2) infinite",
  },
};

window.Creative = Creative;

// keyframes for sleeve-slide + crackle
if (!document.getElementById("__creative-anim")) {
  const s = document.createElement("style");
  s.id = "__creative-anim";
  s.textContent = `
    @keyframes slideOut {
      from { transform: translateX(-12%); opacity: 0; }
      to   { transform: translateX(0);    opacity: 1; }
    }
    @keyframes crackle {
      from { background-position: 0 0; }
      to   { background-position: 73px 41px; }
    }
  `;
  document.head.appendChild(s);
}
