const SECTION_PAD = "92px clamp(20px, 6vw, 80px)";

function ChapterOpener({ num, title, standfirst, dark, align = "left" }) {
  const fg = dark ? "var(--paper-on-ink)" : "var(--ink)";
  const fg2 = dark ? "var(--paper-on-ink-2)" : "var(--ink-3)";
  return (
    <div style={{ borderTop: `1px solid ${dark ? "var(--rule-on-ink)" : "var(--rule-strong)"}`, paddingTop: 22, marginBottom: 56 }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 30, flexWrap: "wrap" }}>
        <div style={{ flex: "1 1 360px" }}>
          <Kicker style={{ marginBottom: 16 }}>Chapter {num}</Kicker>
          <h2 style={{ fontFamily: "var(--font-display)", fontWeight: 700,
            fontSize: "clamp(3rem, 8vw, 7rem)", lineHeight: 0.86, letterSpacing: "-0.045em", color: fg }}>{title}</h2>
        </div>
        {standfirst && (
          <p style={{ flex: "0 1 380px", fontFamily: "var(--font-body)", fontWeight: 500,
            fontSize: "clamp(1.05rem, 1.5vw, 1.35rem)", lineHeight: 1.45, letterSpacing: "-0.01em",
            color: fg2, paddingTop: 8 }}>{standfirst}</p>
        )}
      </div>
    </div>
  );
}

const WORK = [
  {
    id: "speakez",
    kicker: "Hackathon, first place",
    date: "sep 29, 2026",
    title: "SpeakEz",
    note: "Anonymous voice notes you can only hear where they were left. Built in one weekend with Team Wakehaven, and it took first place at the Fall 2026 0→1 Hackathon.",
    marginNote: "this started as the prompt: “a problem students frequently face” ↙",
    link: "github.com/Mulla759/SpeakEz",
    tone: "sienna",
    ratio: "4/3",
    image: null,
    oneLiner: "Hear what campus doesn't say out loud.",
    notes: "Campus is loud about the things that are easy to say. The failing exam, the quiet loneliness, the small win nobody saw stay unsaid. So we built a map of voices instead of a feed: record up to three minutes where it happened, and anyone within 150 m can unlock it. Notes fade after 30 days.",
    specs: [
      ["Team", "Wakehaven: Ilyas Ahmed, Ismail Yusuf, Yahye Abdukadir, Hamza Sigale and me"],
      ["My part", "Most of the build, 47 of 67 commits"],
      ["Built with", "Expo, FastAPI, Postgres + PostGIS, Redis, Parakeet ASR"],
      ["Privacy", "No email or raw GPS stored; unlocks checked server-side"],
    ],
    links: [["View on GitHub", "https://github.com/Mulla759/SpeakEz"], ["Pitch deck", "#"]],
    frameCaption: "Team Wakehaven, right after the results. That's SpeakEz on the screen.",
    frameMeta: "Hackathon, first place · Sep 2026",
  },
  {
    id: "fuelnet",
    kicker: "Internship, Westinghouse Nuclear",
    stat: "2 min → 5 s",
    statCaption: "startup, after I replaced a legacy database",
    title: "FuelNet",
    note: "An operator-facing UI refresh that saves about two hours of onsite downtime per deployment.",
    link: "may 2026 — now",
    tone: "cool",
    ratio: "3/4",
    image: null,
  },
  {
    id: "rolodex",
    kicker: "From the archive",
    tag: "2024",
    title: "Rolodex",
    note: "A recruiter-discovery tool for students who didn't inherit a network. It's where I learned to write copy the way you'd actually text someone.",
    link: "retired",
    tone: "pine",
    ratio: "4/3",
    image: null,
  },
  {
    id: "speakez-wrapped",
    kicker: "On the bench, not built yet",
    tag: "deck, slide 12",
    title: "SpeakEz Wrapped",
    note: "Every semester ends with a story of your daily prompt answers: a highlight reel of the moments you finally said out loud. It's the “coming next” slide of our pitch.",
    link: "from the pitch deck",
    tone: "rose",
    ratio: "1/1",
    image: null,
  },
  {
    id: "gws",
    kicker: "Open source, 2026",
    tag: "live",
    title: "GWS for Dummies",
    note: "Tell your coding agent what you want in plain English. It triages Gmail and makes Tasks and Calendar events through Google's own Workspace CLI. Nothing sent, trashed, or deleted.",
    link: "gws-for-dummies.vercel.app",
    tone: "warm",
    ratio: "4/3",
    image: null,
  },
  {
    id: "promise",
    kicker: "Side project, 2026",
    tag: "early access",
    title: "Promise",
    note: "Keep your word, keep your people: promises to friends, to yourself, and to the world.",
    marginNote: "built because I wanted AI that doesn't send everything to someone else's server",
    link: "joinpromise.vercel.app",
    tone: "sienna",
    ratio: "3/4",
    image: null,
  },
  {
    id: "wunderbar",
    kicker: "Founder, since May 2026",
    stat: "50+",
    statCaption: "paired mock interviews so far",
    title: "WunderBar",
    note: "Peer-to-peer mock technical interviews. Feedback cycles cut matching down to three steps.",
    link: "—",
    tone: "ink",
    ratio: "4/3",
    image: null,
  },
  {
    id: "blackbox",
    kicker: "Hackathon, second of 40+",
    tag: "live",
    title: "BLACKBOX",
    note: "Disaster detection on the live National Weather Service feed, with one AI agent per high-risk household that calls, texts and listens until somebody answers.",
    marginNote: "I kept wondering who checks on the people who can't check in.",
    link: "blackbox-70gc.onrender.com",
    tone: "pine",
    ratio: "4/3",
    image: null,
  },
  {
    id: "odyssey",
    kicker: "Recommender, 2025",
    tag: "2025",
    title: "Odyssey",
    note: "Upload your watch history, get your next favorite film. A local top 100 until you opt in to the full ranker; 1.4K events in its first week.",
    link: "odysrec.com",
    tone: "cool",
    ratio: "1/1",
    image: null,
  },
  {
    id: "colorstack",
    kicker: "Leadership, since Oct 2025",
    stat: "+40%",
    statCaption: "workshop turnout at ColorStack",
    title: "ColorStack at UMN",
    note: "I run academic & professional development: resume, interview and internship workshops for 100+ CS students.",
    link: "—",
    tone: "rose",
    ratio: "4/3",
    image: null,
  },
];

function openExternal(url) {
  if (!url || url === "#" || url === "—") return;
  const u = /^https?:\/\//.test(url) ? url : "https://" + url;
  window.open(u, "_blank", "noopener,noreferrer");
}

function looksLikeUrl(u) {
  return !!u && /\.[a-z]{2,}/i.test(u);
}

function WorkCard({ project, onOpen }) {
  const [hover, setHover] = React.useState(false);
  const frame = project.tag || project.date || (project.kicker ? project.kicker.split(",")[0].trim() : "");
  return (
    <article className="workcard"
      onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      onClick={() => onOpen(project)}
      style={{ cursor: "pointer", transform: hover ? "translateY(-4px)" : "none",
        transition: "transform 320ms var(--ease-cinematic)" }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 12, marginBottom: 9 }}>
        <Micro size={10} color="var(--ink-3)">
          <span style={{ color: "var(--vermilion)", marginRight: 6 }}>—</span>{project.kicker}
        </Micro>
        {project.tag && <Micro size={10} color="var(--vermilion)">{project.tag}</Micro>}
      </div>

      <Plate ratio={project.ratio} tone={project.tone} frame={frame} />

      <h3 style={{ fontFamily: "var(--font-display)", fontWeight: 700, fontSize: "1.7rem",
        lineHeight: 0.98, letterSpacing: "-0.035em", color: "var(--ink)", margin: "14px 0 0" }}>
        {project.title}
      </h3>

      <p style={{ fontFamily: "var(--font-body)", fontSize: "0.9rem", lineHeight: 1.5,
        color: "var(--ink-2)", margin: "9px 0 0" }}>
        {project.note}
      </p>

      {project.stat ? (
        <div style={{ marginTop: 16 }}>
          <div style={{ fontFamily: "var(--font-display)", fontWeight: 700,
            fontSize: "clamp(2rem,3.4vw,3rem)", lineHeight: 1, letterSpacing: "-0.045em",
            color: "var(--ink)" }}>{project.stat}</div>
          <Micro size={9} color="var(--ink-3)" style={{ display: "block", marginTop: 6 }}>{project.statCaption}</Micro>
        </div>
      ) : project.marginNote ? (
        <div style={{ fontFamily: "var(--font-annotation)", fontSize: "1.15rem", lineHeight: 1.2,
          color: "var(--vermilion)", transform: "rotate(-3deg)", transformOrigin: "left center",
          marginTop: 14, maxWidth: "30ch" }}>{project.marginNote}</div>
      ) : null}

      <div style={{ borderTop: "1px solid var(--rule)", marginTop: 18, paddingTop: 10,
        display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 12 }}>
        <Micro size={9} color="var(--ink-3)">{project.link}</Micro>
        <span style={{ color: "var(--vermilion)", fontSize: 12 }}>↗</span>
      </div>
    </article>
  );
}

function DetailNav({ label, name, onClick, align }) {
  return (
    <button onClick={onClick} style={{ background: "none", border: "none", padding: 0,
      textAlign: align, display: "flex", flexDirection: "column", gap: 6, maxWidth: "46%" }}>
      <Micro size={9} color="var(--ink-4)">{label}</Micro>
      <span style={{ fontFamily: "var(--font-display)", fontWeight: 700, fontSize: "1.05rem",
        letterSpacing: "-0.02em", lineHeight: 1.05, color: "var(--ink)" }}>{name}</span>
    </button>
  );
}

function WorkDetail({ project, onClose, onSelect }) {
  const panelRef = React.useRef(null);
  const i = WORK.findIndex(p => p.id === project.id);
  const prev = WORK[(i - 1 + WORK.length) % WORK.length];
  const next = WORK[(i + 1) % WORK.length];

  React.useEffect(() => { if (panelRef.current) panelRef.current.scrollTop = 0; }, [project.id]);

  const specs = project.specs || [
    ["Kind", project.kicker],
    ["Status", project.link],
    ["Note", project.note],
  ];
  const links = project.links || (looksLikeUrl(project.link) ? [[project.link, project.link]] : []);

  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 100,
      background: "rgba(20,18,15,0.62)", display: "flex", alignItems: "center",
      justifyContent: "center", padding: 24, overflow: "auto" }}>
      <div ref={panelRef} onClick={e => e.stopPropagation()}
        style={{ background: "var(--paper-bright)", width: "min(1080px,96vw)",
          maxHeight: "calc(100dvh - 48px)", overflow: "auto" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center",
          gap: 16, flexWrap: "wrap", padding: "16px 28px", borderBottom: "1px solid var(--rule-strong)" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 20, flexWrap: "wrap" }}>
            <Wordmark size={22} />
            <Micro size={10} color="var(--ink-3)">{`work — ${String(i + 1).padStart(2, "0")} / ${String(WORK.length).padStart(2, "0")}`}</Micro>
          </div>
          <button onClick={onClose} style={{ background: "none", border: "1px solid var(--rule-strong)",
            padding: "8px 12px", fontFamily: "var(--font-micro)", fontSize: 10, letterSpacing: "0.16em",
            textTransform: "uppercase", color: "var(--ink)" }}>Close · esc</button>
        </div>

        <div className="cols" style={{ gridTemplateColumns: "repeat(auto-fit, minmax(320px, 1fr))",
          gap: "clamp(28px,4vw,56px)", padding: "clamp(24px,3vw,40px) 28px", alignItems: "start" }}>
          <div>
            <Plate ratio="3/4" tone={project.tone} frame={project.tag || project.date} />
            <div style={{ marginTop: 12 }}>
              <Micro size={9} color="var(--ink-3)">{project.frameCaption || project.note}</Micro>
            </div>
            <div style={{ marginTop: 14 }}>
              <span style={{ fontFamily: "var(--font-annotation)", fontSize: "1.05rem", lineHeight: 1.1,
                color: "var(--vermilion)", display: "inline-block", transform: "rotate(-3deg)" }}>
                swipe for the app →
              </span>
            </div>
            <div style={{ marginTop: 12, display: "flex", alignItems: "baseline", gap: 8 }}>
              <span style={{ color: "var(--vermilion)" }}>—</span>
              <Micro size={9} color="var(--ink-4)">{project.frameMeta || project.kicker}</Micro>
            </div>
          </div>

          <div>
            <h3 style={{ fontFamily: "var(--font-display)", fontWeight: 700,
              fontSize: "clamp(2.2rem,4.6vw,3.6rem)", lineHeight: 0.94, letterSpacing: "-0.04em",
              color: "var(--ink)" }}>{project.title}</h3>

            <p style={{ fontFamily: "var(--font-body)", fontSize: "1.1rem", lineHeight: 1.5,
              color: "var(--ink-2)", marginTop: 14 }}>{project.oneLiner || project.note}</p>

            <div style={{ marginTop: 26 }}>
              <Micro size={9} color="var(--ink-3)">My notes</Micro>
              <p style={{ fontFamily: "var(--font-body)", fontSize: "0.98rem", lineHeight: 1.6,
                color: "var(--ink-2)", marginTop: 9 }}>{project.notes || project.note}</p>
            </div>

            <div style={{ marginTop: 26, borderBottom: "1px solid var(--rule)" }}>
              {specs.map((row, k) => (
                <div key={k} style={{ display: "grid", gridTemplateColumns: "minmax(110px,0.42fr) 1fr",
                  gap: 16, padding: "12px 0", borderTop: "1px solid var(--rule)", alignItems: "baseline" }}>
                  <Micro size={9} color="var(--ink-3)">{row[0]}</Micro>
                  <span style={{ fontFamily: "var(--font-body)", fontSize: "0.95rem", lineHeight: 1.45,
                    color: "var(--ink-2)" }}>{row[1]}</span>
                </div>
              ))}
            </div>

            {links.length > 0 && (
              <div style={{ display: "flex", flexWrap: "wrap", gap: 18, marginTop: 26 }}>
                {links.map(l => (
                  <ArrowLink key={l[0]} dir="↗" onClick={() => openExternal(l[1])}>{l[0]}</ArrowLink>
                ))}
              </div>
            )}
          </div>
        </div>

        <div style={{ borderTop: "1px solid var(--rule-strong)", padding: "18px 28px",
          display: "flex", justifyContent: "space-between", alignItems: "flex-end",
          gap: 16, flexWrap: "wrap" }}>
          <DetailNav label="← Previous" name={prev.title} align="left" onClick={() => onSelect(prev)} />
          <DetailNav label="Next →" name={next.title} align="right" onClick={() => onSelect(next)} />
        </div>
      </div>
    </div>
  );
}

function Work() {
  const [sel, setSel] = React.useState(null);

  React.useEffect(() => {
    if (!sel) return;
    const before = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    const onKey = (e) => { if (e.key === "Escape") setSel(null); };
    window.addEventListener("keydown", onKey);
    return () => {
      document.body.style.overflow = before || "";
      window.removeEventListener("keydown", onKey);
    };
  }, [sel]);

  return (
    <section id="work" className="section" style={{ background: "var(--paper)" }}>
      <div style={{ borderTop: "1px solid var(--rule-strong)", paddingTop: 18,
        marginBottom: "clamp(30px,4vw,54px)" }}>
        <div style={{ display: "flex", flexWrap: "wrap", alignItems: "flex-end",
          justifyContent: "space-between", gap: "18px 40px" }}>
          <div>
            <Micro size={10} color="var(--ink-3)">
              <span style={{ color: "var(--vermilion)", marginRight: 6 }}>—</span>Things I've made, 2023 to now
            </Micro>
            <h2 style={{ fontFamily: "var(--font-display)", fontWeight: 700,
              fontSize: "clamp(3.4rem,9vw,7rem)", lineHeight: 0.88, letterSpacing: "-0.045em",
              color: "var(--ink)", margin: "14px 0 0" }}>Work</h2>
          </div>
          <div style={{ display: "flex", flexWrap: "wrap", alignItems: "flex-end", gap: 18, maxWidth: 440 }}>
            <p style={{ fontFamily: "var(--font-body)", fontSize: "0.95rem", lineHeight: 1.5,
              color: "var(--ink-3)", maxWidth: "34ch", margin: 0 }}>
              Things I've built, shipped, or kept running. Tap any of them for the story, the screens and the links.
            </p>
            <span style={{ fontFamily: "var(--font-annotation)", fontSize: "1.1rem", lineHeight: 1.1,
              color: "var(--vermilion)", display: "inline-block", transform: "rotate(-3deg)",
              whiteSpace: "nowrap" }}>tap one, it opens up ↓</span>
          </div>
        </div>
      </div>

      <Reveal>
        <div className="workgrid">
          {WORK.map(p => <WorkCard key={p.id} project={p} onOpen={setSel} />)}
        </div>
      </Reveal>

      {sel && <WorkDetail project={sel} onClose={() => setSel(null)} onSelect={setSel} />}
    </section>
  );
}

Object.assign(window, { Work, WorkCard, WorkDetail, WORK, ChapterOpener, SECTION_PAD });
