/* casestudy-missionmittelstand-content.jsx — Mission Mittelstand case study.
   Exports <MMCase/>, <MMDisclaimer/>, <MMPrototypeModal/>.
   Depends on core.jsx + casestudy-shared.jsx. */

const MMI = "mm/";
const PROTOTYPE_FILE = "mm/prototype-mobile.html";

/* ---- browser-chrome shot (desktop); URL is static text, never a link ---- */
function MMShot({ src, caption, alt = "Mission Mittelstand landing page", url = "mission-mittelstand.de", badge, badgeKind, placeholder }) {
  const open = useLightbox();
  return (
    <figure className="mm-shot">
      <div className="mm-shell">
        <div className="mm-chrome">
          <span className="mm-dots" aria-hidden="true"><i></i><i></i><i></i></span>
          <span className="mm-url">{url}</span>
          {badge && <span className={"mm-badge" + (badgeKind ? " is-" + badgeKind : "")}>{badge}</span>}
        </div>
        {src ? (
          <button type="button" className="mm-shot-img" data-hot onClick={() => open({ src, alt, caption })} aria-label={"Expand image: " + alt}>
            <img src={src} alt={alt} loading="eager" />
            <span className="mm-zoom" aria-hidden="true">
              <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7" /></svg>
            </span>
          </button>
        ) : <Placeholder label={placeholder} />}
      </div>
      {caption && <figcaption className="cs-cap">{caption}</figcaption>}
    </figure>
  );
}

/* ---- phone bezel (mobile) ---- */
function MMPhone({ src, caption, alt = "Mission Mittelstand on mobile", placeholder, tag, tagKind }) {
  const open = useLightbox();
  return (
    <figure className="mm-phone">
      <div className="mm-phone-frame">
        {tag && <span className={"mm-phone-tag" + (tagKind ? " is-" + tagKind : "")}>{tag}</span>}
        {src ? (
          <button type="button" className="mm-phone-shot" data-hot onClick={() => open({ src, alt, caption })} aria-label={"Expand image: " + alt}>
            <img src={src} alt={alt} loading="eager" />
          </button>
        ) : <Placeholder label={placeholder} />}
      </div>
      {caption && <figcaption className="cs-cap">{caption}</figcaption>}
    </figure>
  );
}

function Placeholder({ label }) {
  return (
    <div className="mm-ph">
      <span className="mm-ph-ico" aria-hidden="true">
        <svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
          <rect x="3" y="3" width="18" height="18" rx="2" /><path d="M3 15l5-5 4 4 3-3 6 6" /><circle cx="8.5" cy="8.5" r="1.5" />
        </svg>
      </span>
      <span className="mm-ph-t">{label || "Screen"}</span>
      <span className="mm-ph-s">Prototype export goes here</span>
    </div>
  );
}

/* ---- animated stat ---- */
function MMStat({ to, pre = "", suf = "", text, label }) {
  const ref = useRef(null);
  const [run, setRun] = useState(false);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    const inView = () => { const r = el.getBoundingClientRect(); return r.top < (window.innerHeight || 800) * 0.85 && r.bottom > 0; };
    if (inView()) { setRun(true); return; }
    const onScroll = () => { if (inView()) { setRun(true); cleanup(); } };
    const t = setTimeout(() => { setRun(true); cleanup(); }, 2500);
    function cleanup() { window.removeEventListener("scroll", onScroll); clearTimeout(t); }
    window.addEventListener("scroll", onScroll, { passive: true });
    return cleanup;
  }, []);
  const [val, setVal] = useState(0);
  useEffect(() => {
    if (!run) return;
    if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) { setVal(to == null ? 0 : to); return; }
    let raf = 0, start = 0, done = false; const target = to == null ? 0 : to; const dur = 1300;
    const tick = (t) => { if (!start) start = t; const p = Math.min((t - start) / dur, 1); setVal(Math.round((1 - Math.pow(1 - p, 3)) * target)); if (p < 1) raf = requestAnimationFrame(tick); else done = true; };
    raf = requestAnimationFrame(tick);
    const fb = setTimeout(() => { if (!done) setVal(target); }, dur + 500);
    return () => { cancelAnimationFrame(raf); clearTimeout(fb); };
  }, [run, to]);
  return (
    <div className="gm-stat" ref={ref}>
      <div className="gm-stat-n">{text ? text : <span className="accent">{pre}{val}{suf}</span>}</div>
      <div className="gm-stat-k">{label}</div>
    </div>
  );
}

function MPlain({ items }) {
  return <ul className="cs-steps">{items.map((t, i) => <li className="cs-li" key={i}>{t}</li>)}</ul>;
}
function KL({ items }) {
  return <ul className="cs-steps">{items.map(([b, t], i) => <li className="cs-li" key={i}><strong>{b}</strong> {t}</li>)}</ul>;
}

/* the five gaps */
const GAPS = [
  ["01 · Value", "Sells the company harder than the worksheet", "The page pitches Mission Mittelstand as an organisation far more than it pitches the worksheet. The template's concrete benefit — the one thing that actually drives a lead-magnet conversion — barely gets a word."],
  ["02 · Momentum", "Two CTAs, a whole page apart", "There are only two calls to action, separated by the entire page. Miss the first one and it's a long scroll with no way to act again."],
  ["03 · Trust", "A \u201Cdownload\u201D that never downloads", "Every button says \u201CVorlage herunterladen\u201D, yet nothing lands on your phone: a modal collects your data and the PDF turns up by email afterwards. The wording promises an instant file the flow never delivers."],
  ["04 · Mobile craft", "Clumsy on a phone", "Huge, low-information sections, a layout that starts to break up near the bottom, and an oversized, unkempt footer — all heavy going on a small screen, where most of this traffic actually is."],
  ["05 · Proof", "Trustpilot, wasted", "A strong 4.5 / 870-review Trustpilot rating exists — but only inside the modal, non-clickable, and never surfaced on the landing page itself. The best proof point is hidden."],
];

/* before evidence (their landing, in phone frames) */
const BEFORE = [
  [MMI + "before-hero.png", "The hero promises \u201CVorlage herunterladen\u201D — download the template."],
  [MMI + "before-modal.png", "\u2026but the click opens a modal form, and the file turns up by email afterwards."],
  [MMI + "before-modal-trustpilot.png", "The 4.5 Trustpilot rating only shows up inside that modal, with no way to click through."],
  [MMI + "before-wissen.png", "Large sections carry very little information — costly on a phone."],
  [MMI + "before-footer.png", "The footer is oversized and unkempt, dragging the page out."],
];

/* after — the redesign, section by section (benefit-led; gif leads) */
const VISUALS = [
  { n: "01", k: "Sticky CTA", h: "The button that follows you down", img: MMI + "sticky-button.gif",
    desc: "My favourite little detail, so it goes first. Scroll past the hero button and a slim CTA slides in and stays within thumb's reach — one tap to the form. It ducks back out the second the form is on screen, so it helps without ever nagging. That long, CTA-less stretch in the middle of the old page? Gone." },
  { n: "02", k: "Value", h: "What you get, in three quick lines", img: MMI + "after-value.png",
    desc: "Right below the hero, three short points make the worksheet's payoff obvious — no scrolling, no guessing. You know what's in the file and why it's worth your details before anything else asks for them." },
  { n: "03", k: "Trust", h: "Hard numbers, then a real face", img: MMI + "after-stats.png",
    desc: "A handful of hard numbers carry the credibility first, then Matthias \u2014 the founder and owner of Mission Mittelstand \u2014 shows up in person. Putting the man behind the company on the page does more for trust than any wall of logos, and the brand finally reads as actual people." },
  { n: "04", k: "FAQ", h: "The section the original never had", img: MMI + "after-faq.png",
    desc: "There was no FAQ before — a real miss, because it pulls triple duty: it settles the last doubts (is it really free? why my phone number?), it nudges conversion by clearing objections right before the form, and it quietly helps SEO visibility on top." },
  { n: "05", k: "Convert", h: "A CTA that tells the truth", img: MMI + "after-form.png",
    desc: "No modal, no bait. The form sits right on the page, the button reads \u201CPDF kostenlos erhalten\u201D, and a line underneath owns up to why each field is there and what happens next. Nothing about the ask should catch you off guard." },
  { n: "06", k: "Footer", h: "A footer that knows when to stop", img: MMI + "after-footer.png",
    desc: "The old footer went on forever. I rebuilt it tight and tidy — smaller, better looking, and genuinely useful as the last thing you scroll past." },
];

/* ---- main article ---- */
function MMCase({ onPrototype }) {
  return (
    <div className="cs-view">

      {/* ── Hero ── */}
      <section className="cs-section cs-hero">
        <div className="cs-wrap">
          <div className="cs-kicker">
            <Reveal><MonoLabel>Case Study · Mission Mittelstand</MonoLabel></Reveal>
            <Reveal as="span" className="mono-sm" style={{ color: "var(--ink-faint)" }}>· 2026 · Landing page · Concept</Reveal>
          </div>
          <div className="ax-hero-grid">
            <Reveal className="ax-hero-text">
              <h1 className="cs-title">A lead magnet,<br /><span className="accent">rebuilt to convert.</span></h1>
              <p className="cs-sub">A mobile-first redesign of Mission Mittelstand's free-worksheet landing page — restructured around a clearer funnel, honest download logic and a stronger case for the template itself.</p>
              <p className="cs-lead">
                Mission Mittelstand offers a free "Mitarbeitergespräch" (employee-review) worksheet as a lead magnet. The single goal of the page is to convince visitors to download it. The company's request was direct: redesign that page to maximise downloads — mobile first, desktop optional — in the Barlow typeface and still unmistakably Mission Mittelstand.
              </p>
              <p className="cs-lead">
                The real focus was the strategy behind the structure: which section does what, why it sits where it does, and why the new build should convert better than the original.
              </p>
              <div className="ax-skip-wrap" style={{ display: "flex", gap: ".8rem", flexWrap: "wrap" }}>
                <a href="#visuals" className="btn btn-accent ax-skip-btn" data-hot>
                  Skip to the visuals
                  <span className="btn-arrow"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 5v14M6 13l6 6 6-6" /></svg></span>
                </a>
                <button type="button" className="btn ax-skip-btn" data-hot onClick={onPrototype}>
                  See the mobile prototype live
                  <span className="btn-arrow"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v12M8 11l4 4 4-4M5 19h14" /></svg></span>
                </button>
              </div>
            </Reveal>
            <Reveal className="ax-hero-media">
              <MMPhone src={MMI + "after-hero.png"} alt="Redesigned Mission Mittelstand mobile hero"
                caption={<><strong>The redesigned mobile hero.</strong> Offer, concrete benefit and trust in the first screen — mobile was both the mandatory brief and the page's primary surface.</>} />
            </Reveal>
          </div>
        </div>
      </section>

      {/* ── Stats ── */}
      <section className="cs-section gm-stats-sec">
        <div className="cs-wrap">
          <div className="gm-statband mm-statband">
            <MMStat to={6} label="SECTIONS IN THE NEW FUNNEL" />
            <MMStat to={5} label="CONVERSION GAPS DIAGNOSED" />
            <MMStat to={3} label="PROTOTYPE DIRECTIONS COMPARED" />
            <MMStat to={1} label="STICKY CTA BRIDGING THE SCROLL" />
          </div>
        </div>
      </section>

      {/* ── Nutshell ── */}
      <section className="cs-section">
        <div className="cs-wrap">
          <div className="cs-head"><h2 className="cs-h">Project in a Nutshell</h2></div>
          <Reveal className="cs-meta">
            <div className="cs-meta-cell">
              <div className="cs-meta-k">My role</div>
              <div className="cs-meta-v">Funnel strategy, landing UX, UX writing, mobile-first UI design and an interactive HTML prototype</div>
            </div>
            <div className="cs-meta-cell">
              <div className="cs-meta-k">Format</div>
              <div className="cs-meta-v">A brief from the company — concept build, no live analytics provided</div>
            </div>
            <div className="cs-meta-cell">
              <div className="cs-meta-k">Constraints</div>
              <div className="cs-meta-v">Barlow type · Mission Mittelstand corporate design · mobile mandatory / desktop optional · realistically buildable, no component libraries</div>
            </div>
          </Reveal>
          <Reveal className="cs-chips cs-mt-m" style={{ justifyContent: "center" }}>
            {["Funnel Strategy", "Landing UX", "UX Writing", "Mobile-First UI", "Conversion Architecture", "Trust & Social Proof", "Interactive Prototype"].map((c) => (
              <span className="tag" key={c}>{c}</span>
            ))}
          </Reveal>
          <div className="cs-grid2 ax-equal cs-mt-l">
            <Reveal className="cs-panel">
              <h4>What I delivered</h4>
              <MPlain items={[
                "A rebuilt information architecture for the worksheet landing page",
                "An interactive mobile HTML prototype as the primary deliverable",
                "A desktop version, built deliberately as an MVP",
                "Reworked CTA copy plus a sticky CTA that follows the scroll",
                "A transparent inline form that replaces the original download modal",
              ]} />
            </Reveal>
            <Reveal className="cs-panel cs-panel-accent">
              <h4>The hypothesis</h4>
              <MPlain items={[
                "Traffic mostly arrives from targeted campaigns, so visitors already have baseline interest",
                "The original page loses them on value, momentum, download logic and mobile craft",
                "A tighter funnel that leads with value and stays honest should lift downloads",
                "Every claim here is a hypothesis, waiting on real data to confirm it",
              ]} />
            </Reveal>
          </div>
        </div>
      </section>

      {/* ── Potential friction points ── */}
      <section className="cs-section" id="process">
        <span className="ax-anchor" aria-hidden="true"></span>
        <div className="cs-wrap">
          <div className="cs-head"><h3 className="cs-h">Potential Friction Points</h3></div>
          <p className="cs-p" style={{ maxWidth: "72ch" }}>
            No analytics came with the brief, so I started where I could: the page itself, who it's for, and where its traffic comes from. Working from the hunch that most visitors land pre-warmed from targeted ads — already curious about the worksheet — the job came down to one thing: stop losing them. Read that way, the original page has five spots where a ready-to-download visitor could quietly slip off the hook.
          </p>
          <div className="mm-gaps mm-gaps--5 cs-mt-l">
            {GAPS.map(([n, t, d]) => (
              <Reveal className="mm-gap" key={n}>
                <span className="mm-gap-n">{n}</span>
                <span className="mm-gap-t">{t}</span>
                <span className="mm-gap-d">{d}</span>
              </Reveal>
            ))}
          </div>

          <p className="cs-p cs-mt-l" style={{ maxWidth: "72ch" }}>
            Some of these land better when you just see them:
          </p>
          <div className="mm-scrollhint cs-mt-s" aria-hidden="true">
            <span>Scroll for more</span>
            <svg width="22" height="12" viewBox="0 0 22 12" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M1 6h19M15 1l5 5-5 5" /></svg>
          </div>
          <div className="mm-carousel cs-mt-s">
            {BEFORE.map(([src, cap]) => (
              <MMPhone key={src} src={src} tag="Before" tagKind="before" alt="Original Mission Mittelstand landing page"
                caption={cap} />
            ))}
          </div>
        </div>
      </section>

      {/* ── How I rebuilt it ── */}
      <section className="cs-section">
        <div className="cs-wrap">
          <div className="cs-head"><h3 className="cs-h">How I Rebuilt It</h3></div>
          <p className="cs-p" style={{ maxWidth: "72ch" }}>
            With no data to lean on, I leaned on process instead. Roughly how the work went, start to finish:
          </p>
          <div className="mm-journey cs-mt-l">
            {[
              ["Read the page like a visitor.", "Went through the original the way its traffic does — on a phone — and worked out who it's really for and where those people come from before changing a thing."],
              ["Mark the friction and the upside.", "Flagged the obvious drop-off points, and just as importantly the spots with clear room to grow."],
              ["Commit to a hypothesis.", "Turned all that into a point of view: lead with the template's value, stay honest about the download, keep a CTA always within reach."],
              ["Sketch three directions.", "Built three structurally different first prototypes and compared them side by side before committing."],
              ["Pick the finalist.", "Chose the direction that served the one goal best — get the worksheet downloaded — and set the other two aside."],
              ["Take it to hi-fi.", "Dressed the winner in full Mission Mittelstand styling, set in Barlow: on brand, and realistic to actually build."],
              ["Make it clickable.", "Shipped it as an interactive, mobile-first HTML prototype you can actually tap through, well past a flat mockup."],
            ].map(([b, t], i) => (
              <Reveal className="mm-jstep" key={i}>
                <span className="mm-jnode" aria-hidden="true">{String(i + 1).padStart(2, "0")}</span>
                <div className="mm-jcard">
                  <h4 className="mm-jt">{b}</h4>
                  <p className="mm-jd">{t}</p>
                </div>
              </Reveal>
            ))}
          </div>
        </div>
      </section>

      {/* ── Visuals (zigzag) ── */}
      <section className="cs-section" id="visuals">
        <span className="ax-anchor" aria-hidden="true"></span>
        <div className="cs-wrap">
          <div className="cs-head"><h3 className="cs-h">The Redesign, Section by Section</h3></div>
          <div className="ax-screens cs-mt-l">
            {VISUALS.map((s, i) => (
              <div className={"ax-screen" + (i % 2 ? " rev" : "")} key={s.n}>
                <Reveal className="ax-screen-text">
                  <div className="ax-index"><span className="ax-index-n">{s.n}</span><span className="ax-index-k">{s.k}</span></div>
                  <h4 className="ax-screen-h">{s.h}</h4>
                  <p className="cs-p">{s.desc}</p>
                </Reveal>
                <Reveal className="ax-screen-media">
                  <MMPhone src={s.img} alt={s.h} />
                </Reveal>
              </div>
            ))}
          </div>
          <Reveal className="mm-proto-cta cs-mt-l">
            <div>
              <h4 className="gm-subh" style={{ marginTop: 0 }}>Try the real thing</h4>
              <p className="cs-p" style={{ margin: 0 }}>The whole flow is a working, self-contained HTML prototype — best opened on a phone.</p>
            </div>
            <button type="button" className="btn btn-accent" data-hot onClick={onPrototype}>
              See the mobile prototype live
              <span className="btn-arrow"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v12M8 11l4 4 4-4M5 19h14" /></svg></span>
            </button>
          </Reveal>
        </div>
      </section>

      {/* ── Desktop ── */}
      <section className="cs-section">
        <div className="cs-wrap">
          <div className="cs-head"><h3 className="cs-h">Desktop, as a Deliberate MVP</h3></div>
          <Reveal>
            <p className="cs-p" style={{ maxWidth: "72ch" }}>
              With mobile as the mandatory focus, I built the desktop version as a conscious MVP: the same funnel and messaging, implemented as a working prototype, with less time on the wider layout. Given more time I'd push the scaling and design richer mid-page sections — but the full story is already here.
            </p>
          </Reveal>
          <Reveal className="mm-mvp-shot">
            <MMShot src={MMI + "after-desktop.png"} url="New Desktop Hero" badge="After" badgeKind="after"
              alt="Redesigned Mission Mittelstand landing page on desktop"
              caption={<>Same funnel, wider canvas. The desktop build is an honest MVP — the story's all here, even if I'd give the layout more room to breathe with more time.</>} />
          </Reveal>
        </div>
      </section>

      {/* ── Learnings ── */}
      <section className="cs-section">
        <div className="cs-prose">
          <div className="cs-head" style={{ justifyContent: "center" }}><h3 className="cs-h">Learnings</h3></div>
          <ul className="cs-steps cs-mt-m">
            {[
              ["Lead with a point of view.", "Even without data, an explicit hypothesis makes the work reviewable and the next step obvious. The redesign is the argument; data is how you'd settle it."],
              ["Honesty is a conversion tactic.", "Matching the CTA promise to what actually happens is the most testable — and probably highest-impact — change in the whole rebuild."],
              ["Lead with the thing, then the brand.", "When the goal is a download, the payoff of the template has to arrive before the company story."],
            ].map(([b, t], i) => <li className="cs-li" key={i}><strong>{b}</strong> {t}</li>)}
          </ul>
        </div>
      </section>

    </div>
  );
}

/* ---- Interactive-prototype download modal ---- */
function MMPrototypeModal({ open, onClose }) {
  const closeRef = useRef(null);
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onKey);
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    closeRef.current && closeRef.current.focus();
    return () => { document.removeEventListener("keydown", onKey); document.body.style.overflow = prev; };
  }, [open, onClose]);
  if (!open) return null;
  return (
    <div className="contact-modal" role="dialog" aria-modal="true" aria-label="Mobile prototype"
      onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="contact-modal-card mm-proto-card">
        <button className="legal-x contact-modal-x" onClick={onClose} aria-label="Close" data-hot ref={closeRef}>
          <svg width="18" height="18" viewBox="0 0 18 18" fill="none" aria-hidden="true"><path d="M3 3l12 12M15 3L3 15" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" /></svg>
        </button>
        <div className="contact-modal-head">
          <MonoLabel>Mobile prototype</MonoLabel>
          <h2 className="contact-modal-title">See it on your phone</h2>
          <p className="contact-modal-sub">This is a self-contained, offline page — it lives only as this one file. Download it, then open it in any browser (a phone, or your browser's mobile view, works best).</p>
        </div>
        <div className="mm-proto-actions">
          <a className="btn btn-accent" href={PROTOTYPE_FILE} download="mission-mittelstand-prototype.html" data-hot onClick={onClose}>
            Download the prototype
            <span className="btn-arrow"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v12M8 11l4 4 4-4M5 19h14" /></svg></span>
          </a>
          <button className="btn" onClick={onClose} data-hot>Maybe later</button>
        </div>
      </div>
    </div>
  );
}

/* ---- Trademark / usage disclaimer (rendered by the shell, below the closing CTA) ---- */
function MMDisclaimer() {
  return (
    <section className="cs-section mm-disclaimer-sec">
      <div className="cs-wrap">
        <div className="mm-disclaimer">
          <span className="mm-disclaimer-ico" aria-hidden="true">
            <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="9" /><path d="M12 8h.01M11 12h1v4h1" /></svg>
          </span>
          <div>
            <p>
              <strong style={{ color: "var(--ink-soft)" }}>Trademarks &amp; usage.</strong> "Mission Mittelstand", the BVMW mark, and all related names, logos, imagery and brand assets shown here are the property of their respective owners. I don't own or claim any rights to them.
            </p>
            <p>
              This case study was produced for a brief from the company, and all brand materials shown were provided to me for that purpose — reproduced here solely to document my work. It is an independent concept: not affiliated with, endorsed by, or an official product of Mission Mittelstand, and it was never deployed on any live site.
            </p>
          </div>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { MMCase, MMDisclaimer, MMPrototypeModal });
