/* Stablex Crypto Trading App — case study.
   Dark base (#0D0D0D), Brand green (#15D997) accent. Headings Clash Display,
   body Cabinet Grotesk (matches home). Content sourced from the real case
   (tilda export); items marked DUMMY are placeholders for Tuna to finalise.
   Structure: impact-first hero → overview/role → goals → before/after →
   discovery → outcomes → decisions → system → final → results → reflection. */

/* real screenshots — inlined blob URL in the standalone bundle, file path live */
const SX_HOME_LIGHT =
  (typeof window !== "undefined" && window.__resources && window.__resources.stablexHomeLight) ||
  "assets/stablex-home-light.png";
const SX_HOME_DARK =
  (typeof window !== "undefined" && window.__resources && window.__resources.stablexHomeDark) ||
  "assets/stablex-home-dark.png";
const SX_OLD_HOME =
  (typeof window !== "undefined" && window.__resources && window.__resources.stablexOldHome) ||
  "assets/stablex-old-home-trim.png";
const SX_OLD_BUYSELL =
  (typeof window !== "undefined" && window.__resources && window.__resources.stablexOldBuysell) ||
  "assets/stablex-old-buysell-trim.png";
const SX_NEW_BUYSELL =
  (typeof window !== "undefined" && window.__resources && window.__resources.stablexNewBuysell) ||
  "assets/stablex-new-buysell.png";

/* ---------- count-up number (fires when scrolled into view) ---------- */
function CountUp({ to, prefix = "", suffix = "", duration = 1300, className = "" }) {
  const ref = React.useRef(null);
  const [val, setVal] = React.useState(0);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    let started = false, raf = 0, t0 = 0, frames = 0;
    const step = (ts) => {
      if (!t0) t0 = ts;
      const p = Math.min(1, (ts - t0) / duration);
      const e = 1 - Math.pow(1 - p, 3);
      setVal(Math.round(e * to));
      if (p < 1) raf = requestAnimationFrame(step);
    };
    const start = () => { if (started) return; started = true; t0 = 0; raf = requestAnimationFrame(step); };
    const inView = () => { const r = el.getBoundingClientRect(); return r.bottom > 0 && r.top < (window.innerHeight || 800) * 0.92; };
    let pollRaf = 0;
    const poll = () => {
      if (started) return;
      if (inView()) { start(); return; }
      if (frames++ < 90) pollRaf = requestAnimationFrame(poll);
    };
    const onScroll = () => { if (!started) poll(); };
    pollRaf = requestAnimationFrame(poll);
    window.addEventListener("scroll", onScroll, { passive: true });
    const tStart = setTimeout(() => { if (!started && inView()) start(); }, 700);
    const tFinal = setTimeout(() => { if (inView()) setVal(to); }, 2400);
    return () => { cancelAnimationFrame(raf); cancelAnimationFrame(pollRaf); clearTimeout(tStart); clearTimeout(tFinal); window.removeEventListener("scroll", onScroll); };
  }, [to, duration]);
  return <span ref={ref} className={className}>{prefix}{val}{suffix}</span>;
}

/* ---------- sticky left-side section navigator ---------- */
function SectionNav() {
  const items = [
    ["overview", "Overview"], ["goals", "Goals"], ["shift", "The shift"],
    ["discovery", "Discovery"], ["decisions", "Decisions"],
    ["design-system", "Design system"], ["results", "Results"],
  ];
  const [active, setActive] = React.useState("overview");
  const [shown, setShown] = React.useState(false);
  React.useEffect(() => {
    const obs = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting) setActive(e.target.id); });
    }, { rootMargin: "-45% 0px -45% 0px", threshold: 0 });
    items.forEach(([id]) => { const el = document.getElementById(id); if (el) obs.observe(el); });
    // reveal the nav after the first scroll
    const onScroll = () => setShown(window.scrollY > 40);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => { obs.disconnect(); window.removeEventListener("scroll", onScroll); };
  }, []);
  return (
    <nav className="hidden md:block fixed left-1/2 z-40"
         style={{
           bottom: 24,
           transform: `translateX(-50%) translateY(${shown ? 0 : 28}px)`,
           opacity: shown ? 1 : 0,
           pointerEvents: shown ? "auto" : "none",
           transition: "opacity .5s cubic-bezier(0.16,1,0.3,1), transform .5s cubic-bezier(0.16,1,0.3,1)",
         }}>
      <div className="flex items-center gap-1 rounded-full px-2 py-2"
           style={{ background: "rgba(20,20,20,0.82)", border: "1px solid rgba(255,255,255,0.1)", backdropFilter: "blur(14px)", WebkitBackdropFilter: "blur(14px)", boxShadow: "0 16px 50px -18px rgba(0,0,0,0.9)" }}>
        {items.map(([id, label]) => {
          const on = active === id;
          return (
            <a key={id} href={`#${id}`}
               className="cs-mono text-[10px] uppercase tracking-[0.16em] rounded-full px-3.5 py-2 transition-all duration-300 whitespace-nowrap"
               style={on
                 ? { background: "#15D997", color: "#0a0a0a", fontWeight: 600 }
                 : { color: "rgba(255,255,255,0.5)" }}>
              {label}
            </a>
          );
        })}
      </div>
    </nav>
  );
}

/* ---------- small building blocks ---------- */
function CSKicker({ children, className = "", dot = true }) {
  return (
    <div className={`flex items-center gap-2.5 cs-mono text-[12px] uppercase tracking-[0.24em] text-white/45 ${className}`}>
      {dot && <span className="size-1.5 rounded-full cs-redbg" />}{children}
    </div>
  );
}

/* DUMMY marker — amber, honest, removable */
function Dummy({ children }) {
  return (
    <span className="inline-flex items-center gap-1.5 align-middle cs-mono text-[10px] uppercase tracking-[0.14em] text-amber-300/80 border border-amber-300/25 bg-amber-300/5 rounded px-1.5 py-0.5">
      <span className="size-1 rounded-full bg-amber-300/70" />placeholder{children ? ` · ${children}` : ""}
    </span>
  );
}

/* VIOLET placeholder — used only in "My influence" rows so it reads apart
   from the green accent and the amber warnings */
function InfluenceBadge() {
  return (
    <span className="inline-flex items-center gap-1.5 align-middle cs-mono text-[12px] uppercase tracking-[0.12em] rounded px-1.5 py-0.5"
          style={{ color: "#A78BFA", background: "rgba(167,139,250,0.1)", border: "1px solid rgba(167,139,250,0.3)" }}>
      <span className="size-1 rounded-full" style={{ background: "#A78BFA" }} />placeholder
    </span>
  );
}

/* dark phone frame with placeholder screen — uses inline colours so it stays a
   dark device even inside light (mist) sections */
function PhoneFrame({ label, width = "210px", className = "", frame = "#998787", screenSrc, style, outerRadius = "2.1rem", innerRadius = "1.6rem", pad = 6 }) {
  return (
    <div className={`relative ${className}`} style={{ width, ...style }}>
      <div className="relative border"
           style={{ background: frame, borderColor: "rgba(0,0,0,.10)", borderRadius: outerRadius, padding: pad, aspectRatio: "9 / 19.5", boxShadow: "0 50px 110px -45px rgba(0,0,0,.9)" }}>
        <div className="relative w-full h-full overflow-hidden grid place-items-center" style={{ borderRadius: innerRadius, ...(screenSrc ? { background: "#000" } : {}) }}>
          {screenSrc ? (
            <img src={screenSrc} alt={label} draggable="false" className="absolute inset-0 w-full h-full object-cover object-top select-none" />
          ) : (
            <div className="absolute inset-0 stripe-placeholder grid place-items-center">
              <span className="cs-mono text-[9px] uppercase tracking-[0.16em] px-3 text-center leading-relaxed" style={{ color: "rgba(255,255,255,.4)" }}>{label}</span>
            </div>
          )}
        </div>
        <div className="absolute top-[10px] left-1/2 -translate-x-1/2 w-14 h-1.5 rounded-full" style={{ background: "rgba(255,255,255,.12)" }} />
      </div>
    </div>
  );
}

/* placeholder figure (screenshot / diagram / grid) — inline colours, device-like */
function Figure({ label, ratio = "16 / 10", caption, className = "" }) {
  return (
    <figure className={className}>
      <div className="relative w-full overflow-hidden rounded-xl" style={{ aspectRatio: ratio, border: "1px solid rgba(255,255,255,.1)" }}>
        <div className="absolute inset-0 stripe-placeholder grid place-items-center">
          <span className="cs-mono text-[9px] uppercase tracking-[0.18em] px-4 text-center" style={{ color: "rgba(255,255,255,.4)" }}>{label}</span>
        </div>
      </div>
      {caption && <figcaption className="mt-3 text-[13px]" style={{ color: "rgba(255,255,255,.45)" }}>{caption}</figcaption>}
    </figure>
  );
}

/* metric block — before → after, big accent after */
function Metric({ label, before, after, big = false }) {
  return (
    <div>
      <CSKicker>{label}</CSKicker>
      <div className="mt-3 cs-display font-bold leading-none flex items-baseline gap-2.5 flex-wrap">
        <span className={`text-white/30 ${big ? "text-[34px] md:text-[44px]" : "text-[24px]"}`}>{before}</span>
        <span className="text-white/20 text-[20px]">→</span>
        <CountUp to={after} suffix="%" className={`cs-red ${big ? "text-[56px] md:text-[80px]" : "text-[34px]"}`} />
      </div>
    </div>
  );
}

/* decision card — featured (accent left border, 3-col) or compact (neutral, stacked) */
function DecisionCard({ d, featured }) {
  return (
    <div className="cs-card rounded-2xl overflow-hidden h-full"
         style={featured ? { borderLeft: "2px solid #15D997" } : undefined}>
      <div className="p-7 md:p-9">
        <div className="flex items-baseline gap-4">
          <span className="cs-display text-white/25 text-2xl tabular-nums">{d.n}</span>
          <h3 className="cs-display font-bold text-[21px] md:text-[26px] leading-[1.14] tracking-tight">{d.title}</h3>
        </div>
        <div className={featured ? "mt-8 grid grid-cols-1 md:grid-cols-3 gap-7 md:gap-8" : "mt-7 space-y-6"}>
          <div>
            <CSKicker>Problem</CSKicker>
            <p className="mt-3 text-[15px] leading-[1.6] text-white/55">{d.problem}</p>
          </div>
          <div className={featured ? "md:border-l cs-divider md:pl-8" : ""}>
            <CSKicker className="cs-red">Decision</CSKicker>
            <p className="mt-3 text-[15px] leading-[1.6] text-white font-medium">{d.decision}</p>
          </div>
          <div className={featured ? "md:border-l cs-divider md:pl-8" : ""}>
            <CSKicker>Why not the alternative</CSKicker>
            <p className="mt-3 text-[15px] leading-[1.6] text-white/55">{d.alt}</p>
          </div>
        </div>
        {/* MY INFLUENCE — violet placeholder, Tuna to write */}
        <div className="mt-7 pt-5 border-t cs-divider flex items-start gap-3">
          <span className="cs-mono text-[13px] uppercase tracking-[0.18em] whitespace-nowrap pt-0.5" style={{ color: "#A78BFA" }}>My influence</span>
          <p className="text-[14px] leading-[1.6] text-white/45">
            <InfluenceBadge /> &nbsp;Tuna to add one line on his specific contribution to this decision — e.g. “I ran the demo-account research, wireframed this flow, and argued down the paywall alternative.”
          </p>
        </div>
      </div>
    </div>
  );
}

/* ---------- the page ---------- */
function StablexCase({ navigate }) {
  const personas = [
    { id: "P1", tag: "New User · Quick Start", color: "#15D997",
      need: "Wants to start trading fast without feeling stupid. Needs the demo to build confidence, not trap them.",
      drives: "Easy Trade & gamified demo" },
    { id: "P2", tag: "Experienced & Strategic Investor", color: "#3B82F6",
      need: "Active on rival platforms. Reads a dense, noisy app as amateur — and an amateur exchange as untrustworthy.",
      drives: "Advanced trading mode" },
    { id: "P3", tag: "The Researcher — Knowledge & Trust", color: "#F59E0B",
      need: "Won't move money until the brand earns it. Reads, compares, verifies before committing.",
      drives: "Trust signals & Crypto World" },
  ];

  const questions = [
    ["Demo account", "Is it actually useful, and how should it behave? Users were getting stuck in demo and never moving to a real, funded account."],
    ["Onboarding", "What's the right first-run flow for an audience that's cautious and security-first?"],
    ["Account levels", "How should the Demo → ID-Verified → Document-Verified transitions feel — without scaring people off?"],
    ["Buy & Sell", "Do starters and pros need the same screen, or two — Basic vs Advanced?"],
    ["Informative content", "Blog, newsletter and education: keep in-app, restructure, or move out — and for which persona?"],
  ];

  const decisions = [
    {
      n: "01", title: "Demo account, reframed as proof of competence",
      problem: "Users found the demo unguided. They practised, felt fine, and lingered — hesitant to cross to a real account. Active conversion stayed low.",
      decision: "A guided, lightly gamified demo: small task-driven milestones and a “you could've done this on real” tone — e.g. “+6.57% in 3 days → upgrade now.” The demo's job became building belief, then handing off.",
      alt: "A hard paywall after the demo. Rejected — research showed trust, not features, was the barrier; a paywall punishes hesitation instead of converting it.",
    },
    {
      n: "02", title: "Onboarding that starts in demo, upgrades automatically",
      problem: "A long KYC form up front, plus three account statuses (Demo L1 / ID-Verified L2 / Document-Verified L3), made the most important transitions the most confusing ones.",
      decision: "Start onboarding inside the demo with a minimal form; auto-promote to L2 on first fiat deposit. With stakeholders we confirmed L3 wasn't critical — Trading + Deposit live at L2; L3 only adds crypto transfer.",
      alt: "Surface all three levels up front for transparency. Rejected — it front-loaded friction and decision fatigue onto exactly the cautious user we were trying to reassure.",
    },
    {
      n: "03", title: "Buy & Sell split into Basic and Advanced",
      problem: "A detailed trading screen overwhelmed starters; a simple one felt amateur to pros. One surface couldn't serve opposite cognitive loads honestly.",
      decision: "Two distinct modes: a calm Basic flow reachable from the bottom nav, and an Advanced view opened from a coin's market page — each tuned to its persona.",
      alt: "One adaptive UI that morphs per user. Rejected — persona research showed the loads were opposite, not adjacent; a single morphing surface would compromise both.",
    },
    {
      n: "04", title: "Editorial content consolidated into “Crypto World”",
      problem: "Blog, newsletter and education were scattered and pitched at the wrong level — too basic for pros, too dense for starters — adding noise to the core trading jobs.",
      decision: "Unified Blog + Newsletter under one home, “Crypto World” (Blog / Analysis / Campaigns), and moved long-form education to the web — where, with stakeholders, we agreed it performs better.",
      alt: "Persona-filtered in-app content feeds. Rejected — heavier to maintain and still noisy in-app; the web was the right home for training material.",
    },
  ];

  // timeline tracks (weeks), overlapping — total span 22 weeks
  const TL_TOTAL = 22;
  const tracks = [
    { label: "Research", start: 0, len: 3, op: 1 },
    { label: "UX wireframes", start: 2, len: 10, op: 0.7 },
    { label: "UI & design system", start: 8, len: 12, op: 0.5 },
  ];
  const milestones = [
    { at: 3, label: "Synthesis" },
    { at: 9, label: "Stakeholder review" },
    { at: 20, label: "Handoff" },
  ];

  return (
    <div className="stablex-case relative" style={{ background: "#0D0D0D" }}>
      <style>{`
        .stablex-case { --red:#15D997; font-family:'Cabinet Grotesk',system-ui,sans-serif; color:#fff; }
        .stablex-case h1,.stablex-case h2,.stablex-case h3,.stablex-case .cs-display{
          font-family:'Clash Display',system-ui,sans-serif; letter-spacing:-0.02em; font-weight:500;
        }
        .stablex-case h1.font-bold{ font-weight:400; }
        .stablex-case .cs-display.font-bold{ font-weight:600; }
        .stablex-case h2.font-normal{ font-weight:400; }
        .stablex-case .cs-mono{ font-family:'Cabinet Grotesk',system-ui,sans-serif; }
        .stablex-case .cs-red{ color:var(--red); }
        .stablex-case .cs-redbg{ background:var(--red); }
        .stablex-case .cs-card{ background:#141414; border:1px solid rgba(255,255,255,.08); }
        .stablex-case .cs-sunken{ background:rgba(255,255,255,0.02); border:1px solid rgba(255,255,255,.06); }
        .stablex-case .cs-divider{ border-color:rgba(255,255,255,.08); }
        .stablex-case section[id]{ scroll-margin-top:88px; }

        /* ── LIGHT sections: mist-green (.sec-light) or white (.sec-white) ── */
        .stablex-case .sec-light{ background:#EAF3EF; }
        .stablex-case .sec-white{ background:#FFFFFF; }
        .stablex-case :is(.sec-light,.sec-white){ color:#0F1A16; }
        .stablex-case .sec-light .cs-card{ background:#ffffff; border-color:rgba(15,26,22,.10); }
        .stablex-case .sec-white .cs-card{ background:#F3F6F4; border-color:rgba(15,26,22,.08); }
        .stablex-case :is(.sec-light,.sec-white) .cs-sunken{ background:rgba(15,26,22,.04); border-color:rgba(15,26,22,.08); }
        .stablex-case :is(.sec-light,.sec-white) .cs-divider{ border-color:rgba(15,26,22,.12); }
        .stablex-case :is(.sec-light,.sec-white) .cs-red{ color:#0A8F60; }
        .stablex-case :is(.sec-light,.sec-white) .cs-redbg{ background:#0A8F60; }
        /* flip white-opacity text utilities to ink-green on light */
        .stablex-case :is(.sec-light,.sec-white) .text-white{ color:#0F1A16; }
        .stablex-case :is(.sec-light,.sec-white) .text-white\\/90{ color:rgba(15,26,22,.92); }
        .stablex-case :is(.sec-light,.sec-white) .text-white\\/85{ color:rgba(15,26,22,.86); }
        .stablex-case :is(.sec-light,.sec-white) .text-white\\/80{ color:rgba(15,26,22,.8); }
        .stablex-case :is(.sec-light,.sec-white) .text-white\\/75{ color:rgba(15,26,22,.74); }
        .stablex-case :is(.sec-light,.sec-white) .text-white\\/70{ color:rgba(15,26,22,.7); }
        .stablex-case :is(.sec-light,.sec-white) .text-white\\/65{ color:rgba(15,26,22,.64); }
        .stablex-case :is(.sec-light,.sec-white) .text-white\\/60{ color:rgba(15,26,22,.6); }
        .stablex-case :is(.sec-light,.sec-white) .text-white\\/55{ color:rgba(15,26,22,.55); }
        .stablex-case :is(.sec-light,.sec-white) .text-white\\/50{ color:rgba(15,26,22,.5); }
        .stablex-case :is(.sec-light,.sec-white) .text-white\\/45{ color:rgba(15,26,22,.5); }
        .stablex-case :is(.sec-light,.sec-white) .text-white\\/40{ color:rgba(15,26,22,.45); }
        .stablex-case :is(.sec-light,.sec-white) .text-white\\/30{ color:rgba(15,26,22,.34); }
        .stablex-case :is(.sec-light,.sec-white) .text-white\\/20{ color:rgba(15,26,22,.24); }
        /* flip the few white-opacity borders / fills used in light sections */
        .stablex-case :is(.sec-light,.sec-white) .border-white\\/10{ border-color:rgba(15,26,22,.12); }
        .stablex-case :is(.sec-light,.sec-white) .border-white\\/12{ border-color:rgba(15,26,22,.14); }
        .stablex-case :is(.sec-light,.sec-white) .border-white\\/15{ border-color:rgba(15,26,22,.16); }
        .stablex-case :is(.sec-light,.sec-white) .bg-white\\/5{ background:rgba(15,26,22,.05); }
        .stablex-case :is(.sec-light,.sec-white) .bg-white\\/10{ background:rgba(15,26,22,.08); }
      `}</style>

      <SectionNav />

      {/* ════ HERO — impact-first, two-column ════ */}
      <header className="relative min-h-screen w-full overflow-hidden flex items-center">
        <div className="absolute inset-0 pointer-events-none" style={{
          backgroundImage: "linear-gradient(rgba(255,255,255,.04) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.04) 1px, transparent 1px)",
          backgroundSize: "64px 64px",
          maskImage: "radial-gradient(ellipse at 30% 30%, black 30%, transparent 80%)",
          WebkitMaskImage: "radial-gradient(ellipse at 30% 30%, black 30%, transparent 80%)",
        }} />
        <div className="absolute top-1/2 right-0 -translate-y-1/2 w-[700px] h-[560px] rounded-full pointer-events-none"
             style={{ background: "radial-gradient(closest-side, rgba(21,217,151,.18), transparent 72%)", filter: "blur(30px)" }} />

        <div className="relative max-w-[1180px] mx-auto px-6 w-full pt-28 pb-16 grid grid-cols-1 lg:grid-cols-[1.12fr_0.88fr] gap-12 lg:gap-10 items-center">
          {/* LEFT — text */}
          <div>
            <Reveal>
              <div className="flex flex-wrap gap-x-3 gap-y-2 cs-mono text-[12px] uppercase tracking-[0.2em] text-white/45">
                {["Design Lead & UX Designer", "Research Direction", "UI Direction"].map((t, i) => (
                  <span key={t} className="inline-flex items-center gap-3 whitespace-nowrap">
                    {i > 0 && <span className="text-white/20">·</span>}{t}
                  </span>
                ))}
              </div>
            </Reveal>
            <Reveal delay={70}>
              <h1 className="mt-6 font-bold text-[32px] md:text-[46px] lg:text-[50px] leading-[1.1] tracking-tight">
                Turkey&apos;s first bank-backed<br />crypto exchange,<br /><span style={{ color: "#E8001C" }}>redesigned to feel like one.</span>
              </h1>
            </Reveal>

            {/* framed impact — two separate boxes */}
            <Reveal delay={150}>
              <div className="mt-9 grid grid-cols-1 sm:grid-cols-2 gap-4 max-w-[560px]">
                <div className="cs-card rounded-2xl p-6">
                  <Metric label="Onboarding abandonment" before="82%" after={59} />
                </div>
                <div className="cs-card rounded-2xl p-6">
                  <Metric label="Active users" before="22%" after={45} />
                </div>
              </div>
            </Reveal>
          </div>

          {/* RIGHT — two overlapping mockups */}
          <Reveal delay={140}>
            <div className="relative h-[440px] md:h-[560px]">
              <div className="absolute z-10" style={{ right: 0, top: "50%", transform: "translateY(-46%) rotate(5deg)" }}>
                <PhoneFrame label="[ final · trade ]" width="240px" screenSrc={SX_HOME_DARK} />
              </div>
              <div className="absolute z-20" style={{ left: "16%", top: "50%", transform: "translateY(-58%) rotate(-3deg)" }}>
                <PhoneFrame label="[ final · home ]" width="240px" screenSrc={SX_HOME_LIGHT} />
              </div>
            </div>
          </Reveal>
        </div>
      </header>

      {/* ════ §1 — OVERVIEW · ROLE · TIMELINE ════ */}
      <section id="overview" className="sec-light py-20 md:py-28 lg:py-32 border-t cs-divider">
        <div className="max-w-[1180px] mx-auto px-6 grid grid-cols-1 lg:grid-cols-[1.1fr_0.9fr] gap-12 lg:gap-20">
          <div>
            <Reveal><CSKicker dot={false}>Overview</CSKicker></Reveal>
            <Reveal delay={80}>
              <h2 className="mt-5 text-[24px] md:text-[32px] leading-[1.15] tracking-tight text-balance max-w-[20ch]">
                <span style={{ color: "#E8001C" }}>A market with a trust problem,</span> and the first brand positioned to fix it.
              </h2>
            </Reveal>
            <Reveal delay={140}>
              <p className="mt-6 text-[18px] leading-[1.7] text-white/75 max-w-[58ch]">
                Turkey&apos;s crypto market had a serious trust problem and no bank- or investment-backed
                exchange to anchor it. In late 2023, Stablex was acquired by AK Investment — becoming the
                first credibility-backed exchange. But the product met neither user nor institutional
                expectations. As the lead designer of the sole agency, my job was the redesign that made it
                feel as credible as the company behind it.
              </p>
            </Reveal>
          </div>

          <div className="space-y-5 lg:mt-9">
            {/* role */}
            <Reveal>
              <div className="cs-sunken rounded-2xl p-6">
                <span className="inline-flex cs-mono text-[12px] uppercase tracking-[0.24em] text-white/55 border border-white/12 rounded-full px-3 py-1.5" style={{ background: "#EAF3EF" }}>My role</span>
                <div className="mt-4 text-[18px] text-white leading-snug">Design Lead &amp; UX Designer</div>
                <p className="mt-3 text-[15px] leading-[1.6] text-white/60">
                  I owned the UX design end-to-end and led a Researcher and a UI Designer working under me —
                  steering their process and signing off the final decisions on both research and UI.
                </p>
                <ul className="mt-4 space-y-2 text-[14px] text-white/55 leading-relaxed">
                  {["Shaped the in-depth interview study with the researcher",
                    "Built the personas & user journey maps",
                    "Ideation, and steering iterations with stakeholders to land decisions",
                    "UX wireframes for every screen; UI concept direction & final QA"].map((t) => (
                    <li key={t} className="flex gap-2.5"><span className="cs-red mt-px">—</span><span>{t}</span></li>
                  ))}
                </ul>
              </div>
            </Reveal>
          </div>
        </div>
      </section>

      {/* ════ §2 — GOALS · AUDIENCE ════ */}
      <section id="goals" className="sec-white py-20 md:py-28 lg:py-32 border-t cs-divider">
        <div className="max-w-[1180px] mx-auto px-6">
          <Reveal><CSKicker dot={false}>Goals &amp; audience</CSKicker></Reveal>
          <Reveal delay={80}>
            <h2 className="mt-5 text-[24px] md:text-[32px] leading-[1.15] tracking-tight max-w-[22ch]">
              Clear targets, set against a cautious, trust-driven audience.
            </h2>
          </Reveal>

          <div className="mt-12 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 items-stretch">
            {/* goals */}
            {[
              ["Onboarding abandonment", "below 65%", "from 82% baseline"],
              ["Active users", "over 30%", "from 22% baseline"],
              ["Store downloads", "+200%", "ad-driven · indirect"],
            ].map(([k, v, ctx], i) => (
              <Reveal key={k} delay={i * 70} className="h-full">
                <div className="cs-card rounded-2xl p-5 h-full flex flex-col">
                  <CSKicker>{k}</CSKicker>
                  <div className="mt-4 cs-display font-bold text-[30px] leading-none cs-red">{v}</div>
                  <div className="mt-3 text-[13px] text-white/45 leading-snug">{ctx}</div>
                </div>
              </Reveal>
            ))}
            {/* audience */}
            <Reveal delay={210} className="h-full">
              <div className="cs-card rounded-2xl p-5 h-full flex flex-col">
                <CSKicker>Target audience</CSKicker>
                <div className="mt-4 flex flex-wrap gap-2 content-start">
                  {["Security-first", "Simplicity", "Institutional trust", "Low risk", "Curated coins"].map((t) => (
                    <span key={t} className="cs-mono text-[12px] uppercase tracking-[0.12em] text-white/55 border border-white/12 rounded-full px-3 py-1.5">{t}</span>
                  ))}
                </div>
              </div>
            </Reveal>
          </div>

          {/* timeline — overlapping gantt, full width */}
          <Reveal delay={120}>
            <div className="mt-8 cs-sunken rounded-2xl p-6 md:p-8">
              <CSKicker dot={false}>Timeline · ~6 months</CSKicker>
              <div className="mt-6 space-y-3.5">
                {tracks.map((t) => (
                  <div key={t.label} className="flex items-center gap-4">
                    <div className="w-36 shrink-0 text-[13px] text-white/70">{t.label}</div>
                    <div className="relative flex-1 h-6">
                      <div className="absolute top-1/2 -translate-y-1/2 h-2.5 rounded-full"
                           style={{ left: `${(t.start / TL_TOTAL) * 100}%`, width: `${(t.len / TL_TOTAL) * 100}%`, background: "#15D997", opacity: t.op }} />
                    </div>
                    <div className="w-12 text-right cs-mono text-[12px] text-white/45">{t.len} wk</div>
                  </div>
                ))}
              </div>
              {/* milestone markers */}
              <div className="mt-1 flex items-start gap-4">
                <div className="w-36 shrink-0" />
                <div className="relative flex-1 h-10">
                  {milestones.map((m) => (
                    <div key={m.label} className="absolute top-0 flex flex-col items-center -translate-x-1/2" style={{ left: `${(m.at / TL_TOTAL) * 100}%` }}>
                      <span className="size-1.5 rounded-full" style={{ background: "#0F1A16" }} />
                      <span className="mt-1.5 cs-mono text-[9px] uppercase tracking-[0.1em] text-white/45 whitespace-nowrap">{m.label}</span>
                    </div>
                  ))}
                </div>
                <div className="w-12 shrink-0" />
              </div>
            </div>
          </Reveal>
        </div>
      </section>

      {/* ════ §3 — BEFORE / AFTER money-shot ════ */}
      <section id="shift" className="py-20 md:py-28 lg:py-32 border-t cs-divider">
        <div className="max-w-[1180px] mx-auto px-6">
          <Reveal><CSKicker dot={false}>The shift</CSKicker></Reveal>
          <Reveal delay={80}>
            <h2 className="mt-5 text-[24px] md:text-[32px] leading-[1.15] tracking-tight max-w-[24ch]">
              The brand promise and the product were arguing with each other.
            </h2>
          </Reveal>

          <div className="mt-10 grid grid-cols-1 md:grid-cols-2 gap-8 md:gap-6 items-stretch">
            <Reveal>
              <div className="cs-card rounded-2xl p-6 md:p-8 h-full">
                <div className="flex items-center gap-3"><span className="cs-mono text-[12px] uppercase tracking-[0.18em] text-white/40">Before</span><span className="flex-1 h-px bg-white/10" /></div>
                <div className="mt-6 flex gap-3 justify-center">
                  <PhoneFrame label="[ old app · home ]" width="140px" className="rotate-[-4deg] opacity-70" screenSrc={SX_OLD_HOME} outerRadius="1.05rem" innerRadius="0.8rem" pad={3} />
                  <PhoneFrame label="[ old app · buy/sell ]" width="150px" className="-translate-y-3 opacity-80" screenSrc={SX_OLD_BUYSELL} outerRadius="1.05rem" innerRadius="0.8rem" pad={3} />
                </div>
                <p className="mt-7 text-[15px] leading-[1.65] text-white/60">
                  Chaotic, beginner-hostile, trust-eroding — visual noise that read as amateur to pros and
                  overwhelmed starters.
                </p>
              </div>
            </Reveal>
            <Reveal delay={100}>
              <div className="cs-card rounded-2xl p-6 md:p-8 h-full" style={{ borderColor: "rgba(21,217,151,.35)" }}>
                <div className="flex items-center gap-3"><span className="cs-mono text-[12px] uppercase tracking-[0.18em] cs-red">After</span><span className="flex-1 h-px" style={{ background: "rgba(21,217,151,.3)" }} /></div>
                <div className="mt-6 flex gap-3 justify-center">
                  <PhoneFrame label="[ new app · home ]" width="140px" className="rotate-[-4deg]" screenSrc={SX_HOME_LIGHT} outerRadius="1.05rem" innerRadius="0.8rem" pad={3} />
                  <PhoneFrame label="[ new app · basic buy ]" width="150px" className="-translate-y-3" screenSrc={SX_NEW_BUYSELL} outerRadius="1.05rem" innerRadius="0.8rem" pad={3} />
                </div>
                <p className="mt-7 text-[15px] leading-[1.65] text-white/75">
                  One calm hierarchy, institutional typography, charts that breathe — a product that finally
                  looks like the bank standing behind it.
                </p>
              </div>
            </Reveal>
          </div>
        </div>
      </section>

      {/* ════ §4 — DISCOVERY ════ */}
      <section id="discovery" className="sec-light py-20 md:py-28 lg:py-32 border-t cs-divider">
        <div className="max-w-[1180px] mx-auto px-6">
          <Reveal><CSKicker dot={false}>Discovery</CSKicker></Reveal>
          <Reveal delay={80}>
            <h2 className="mt-5 font-normal text-[24px] md:text-[32px] leading-[1.18] tracking-tight max-w-[20ch]">
              Five questions we had to answer before drawing a single screen.
            </h2>
          </Reveal>

          <div className="mt-12 grid grid-cols-1 md:grid-cols-2 gap-x-12 gap-y-px">
            {questions.map(([q, body], i) => (
              <Reveal key={q} delay={(i % 2) * 70}>
                <div className="flex gap-5 py-6 border-t cs-divider">
                  <span className="cs-display text-white/20 text-[22px] tabular-nums leading-none pt-1">{String(i + 1).padStart(2, "0")}</span>
                  <div>
                    <h3 className="text-[18px] md:text-[20px] leading-tight">{q}</h3>
                    <p className="mt-2 text-[15px] leading-[1.6] text-white/55 max-w-[46ch]">{body}</p>
                  </div>
                </div>
              </Reveal>
            ))}
          </div>

          {/* method strip — sunken */}
          <Reveal delay={120}>
            <div className="mt-10 grid grid-cols-1 md:grid-cols-3 gap-5">
              <div className="cs-sunken rounded-2xl p-6">
                <CSKicker>Benchmarking</CSKicker>
                <p className="mt-3 text-[15px] leading-[1.6] text-white/65">Local exchanges + global leaders — Binance, Coinbase, Kraken, KuCoin.</p>
              </div>
              <div className="cs-sunken rounded-2xl p-6">
                <CSKicker>Interviews</CSKicker>
                <p className="mt-3 text-[15px] leading-[1.6] text-white/65">12 moderated in-depth sessions — 6 starters, 6 pros.</p>
              </div>
              <div className="cs-sunken rounded-2xl p-6">
                <CSKicker>Synthesis</CSKicker>
                <p className="mt-3 text-[15px] leading-[1.6] text-white/65">Affinity mapping into 3 personas and 3 journey maps.</p>
              </div>
            </div>
          </Reveal>
        </div>
      </section>

      {/* ════ §5 — OUTCOMES (personas + journeys) ════ */}
      <section id="outcomes" className="sec-white py-20 md:py-28 lg:py-32 border-t cs-divider">
        <div className="max-w-[1180px] mx-auto px-6">
          <Reveal><CSKicker dot={false}>Research outcomes</CSKicker></Reveal>
          <Reveal delay={80}>
            <h2 className="mt-5 text-[24px] md:text-[32px] leading-[1.15] tracking-tight max-w-[18ch]">
              Three people the product had to serve.
            </h2>
          </Reveal>

          <div className="mt-12 grid grid-cols-1 md:grid-cols-3 gap-5">
            {personas.map((p, i) => (
              <Reveal key={p.id} delay={i * 80}>
                <div className="cs-card rounded-2xl p-7 h-full flex flex-col" style={{ borderTop: `2px solid ${p.color}` }}>
                  <div className="flex items-center gap-3">
                    <span className="grid place-items-center size-9 rounded-lg cs-mono text-[12px] font-semibold" style={{ background: `${p.color}1f`, color: p.color }}>{p.id}</span>
                    <span className="text-[14px] text-white/85 leading-tight">{p.tag}</span>
                  </div>
                  <p className="mt-5 text-[15px] leading-[1.65] text-white/65 flex-1">{p.need}</p>
                  <div className="mt-6 pt-5 border-t cs-divider text-[13px] text-white/50">
                    <span style={{ color: p.color }}>drives → </span>{p.drives}
                  </div>
                </div>
              </Reveal>
            ))}
          </div>
        </div>
      </section>

      {/* ════ §6 — DECISIONS ════ */}
      <section id="decisions" className="py-20 md:py-28 lg:py-32 border-t cs-divider">
        <div className="max-w-[1180px] mx-auto px-6">
          <Reveal><CSKicker dot={false}>Key decisions</CSKicker></Reveal>
          <Reveal delay={80}>
            <h2 className="mt-5 font-normal text-[24px] md:text-[32px] leading-[1.18] tracking-tight max-w-[24ch]">
              Four decisions — and the alternatives I turned down.
            </h2>
          </Reveal>

          <div className="mt-10 space-y-4">
            {/* featured: first two, full width */}
            {decisions.slice(0, 2).map((d) => (
              <Reveal key={d.n}><DecisionCard d={d} featured /></Reveal>
            ))}
            {/* neutral: last two, side by side */}
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
              {decisions.slice(2).map((d) => (
                <Reveal key={d.n}><DecisionCard d={d} /></Reveal>
              ))}
            </div>
          </div>
        </div>
      </section>

      {/* ════ §7 — DESIGN SYSTEM ════ */}
      <section id="design-system" className="sec-light py-20 md:py-28 lg:py-32 border-t cs-divider">
        <div className="max-w-[1180px] mx-auto px-6">
          <Reveal><CSKicker dot={false}>Design system</CSKicker></Reveal>
          <Reveal delay={80}>
            <div className="mt-6 cs-card rounded-2xl p-7 md:p-10 grid grid-cols-1 lg:grid-cols-[0.95fr_1.05fr] gap-10 lg:gap-14 items-center">
              <div>
                <h2 className="cs-display font-bold text-[24px] md:text-[32px] leading-[1.12] tracking-tight max-w-[20ch]">
                  A token-based Figma system, built to be handed off.
                </h2>
                <p className="mt-5 text-[16px] leading-[1.7] text-white/65 max-w-[46ch]">
                  Color, type, spacing and components as tokens — so one calm hierarchy survives contact with
                  every module and the teams shipping them.
                </p>
                <p className="mt-5 text-[14px] leading-[1.6] text-white/40">
                  <Dummy>module list</Dummy> &nbsp;System scope &amp; handoff specifics (module count, component/token counts, handoff format) — Tuna to confirm the real numbers.
                </p>
              </div>
              <Figure label="[ component grid · color tokens · button states · type scale ]" ratio="16 / 10" />
            </div>
          </Reveal>
        </div>
      </section>

      {/* ════ §8 — FINAL SCREENS ════ */}
      <section id="final" className="sec-white py-20 md:py-28 lg:py-32 border-t cs-divider">
        <div className="max-w-[1180px] mx-auto px-6">
          <Reveal><CSKicker dot={false} className="justify-center">Final design</CSKicker></Reveal>
          <Reveal delay={80}>
            <h2 className="mt-5 text-center text-[24px] md:text-[32px] leading-[1.15] tracking-tight">The product, shipped.</h2>
          </Reveal>
          <div className="mt-10 grid grid-cols-3 gap-4 md:gap-7 items-start">
            {[
              { l: "[ home ]", up: true }, { l: "[ basic buy-sell ]", up: false }, { l: "[ crypto world ]", up: true },
            ].map((s, i) => (
              <Reveal key={i} delay={(i % 3) * 70}>
                <PhoneFrame label={s.l} width="100%" className={s.up ? "md:-translate-y-8" : "md:translate-y-8"} />
              </Reveal>
            ))}
          </div>
          <Reveal delay={120}>
            <div className="mt-12 text-center">
              <a href="#" onClick={(e) => e.preventDefault()} className="inline-flex items-center gap-2 cs-mono text-[12px] uppercase tracking-[0.18em] text-white/70 border border-white/15 rounded-full px-5 py-2.5 hover:text-white hover:border-white/30 transition-colors">
                View the Figma file <span aria-hidden>→</span>
              </a>
            </div>
          </Reveal>
        </div>
      </section>

      {/* ════ §9 — RESULTS (proof / substantiation) ════ */}
      <section id="results" className="py-24 md:py-32 lg:py-40 border-t cs-divider">
        <div className="max-w-[1100px] mx-auto px-6">
          <Reveal><CSKicker dot={false}>Results · the proof</CSKicker></Reveal>
          <div className="mt-12 grid grid-cols-1 md:grid-cols-2 gap-10 md:gap-12">
            <Reveal>
              <div>
                <Metric label="Onboarding abandonment" before="82%" after={59} big />
                <p className="mt-5 text-[15px] leading-[1.6] text-white/60 max-w-[42ch]">
                  Beat the &lt;65% target. <Dummy>method</Dummy> &nbsp;Measured at 3 months post-launch via app analytics funnel — Tuna to confirm sample size &amp; definition.
                </p>
              </div>
            </Reveal>
            <Reveal delay={120}>
              <div>
                <Metric label="Active users" before="22%" after={45} big />
                <p className="mt-5 text-[15px] leading-[1.6] text-white/60 max-w-[42ch]">
                  Beat the &gt;30% target. <Dummy>method</Dummy> &nbsp;First cohort, first 3 months. “Active” = ≥1 trade/week — Tuna to confirm. Impact shared with new marketing.
                </p>
              </div>
            </Reveal>
          </div>

          {/* reflection + next */}
          <Reveal delay={160}>
            <div className="mt-12 pt-9 border-t cs-divider grid grid-cols-1 md:grid-cols-2 gap-10">
              <div>
                <CSKicker>What I'd do differently</CSKicker>
                <p className="mt-4 text-[16px] leading-[1.7] text-white/70 max-w-[48ch]">
                  <Dummy /> &nbsp;A short honest reflection — e.g. “I'd A/B test the gamified KYC step before launch rather than after, and instrument the demo-to-real handoff more tightly.” Tuna to finalise.
                </p>
              </div>
              <div>
                <CSKicker>What's next</CSKicker>
                <p className="mt-4 text-[16px] leading-[1.7] text-white/70 max-w-[48ch]">
                  The active-user goal was &gt;30% in year one — 45% in the first cohort puts the product
                  well ahead, with the retention loop the next thing to push.
                </p>
              </div>
            </div>
          </Reveal>

          {/* prev / next case */}
          <Reveal delay={200}>
            <div className="mt-12 pt-8 border-t cs-divider flex flex-wrap items-center justify-between gap-4">
              <button onClick={() => navigate("home")} className="cs-mono text-[12px] uppercase tracking-[0.18em] text-white/55 hover:text-white transition-colors">← Back to work</button>
              <a href="mailto:tunaaldemir@gmail.com" className="cs-mono text-[12px] uppercase tracking-[0.18em] text-white/55 hover:text-white transition-colors">Get in touch →</a>
            </div>
          </Reveal>
        </div>
      </section>
    </div>
  );
}

window.StablexCase = StablexCase;
