// Case card + Work / Services / Sprint / Contact views
const VW_NS = window.DeckhausDesignSystem_ca5964;

function CaseCard({ c, onClick }) {
  const { Badge } = VW_NS;
  return (
    <a href="#" onClick={(e) => { e.preventDefault(); (onClick || (() => window.DH_NAV("work")))(); }}
      className="dh-card dh-card--interactive dh-card--flush" style={{ display: "block", textDecoration: "none" }}>
      <div style={{ aspectRatio: "4 / 3", background: `linear-gradient(150deg, ${c.tone}, #0b0b0d)`, position: "relative", borderBottom: "1px solid var(--border-subtle)" }}>
        <div style={{ position: "absolute", inset: 0, backgroundImage: "linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px)", backgroundSize: "40px 40px", opacity: .7 }} />
        <img src="assets/logos/deckhaus-mark-white.svg" style={{ position: "absolute", left: 22, top: 22, height: 26, opacity: .85 }} alt="" />
        {c.fig ? <span style={{ position: "absolute", right: 22, top: 24, fontFamily: "var(--font-mono)", fontSize: 11, lineHeight: 1.4, letterSpacing: ".14em", textTransform: "uppercase", color: "rgba(244,244,239,.5)" }}>Fig. {c.fig}</span> : null}
        <div style={{ position: "absolute", left: 22, bottom: 20, right: 22, display: "flex", flexDirection: "column", gap: 10, alignItems: "flex-start" }}>
          {c.status ? <span style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, lineHeight: 1, letterSpacing: ".14em", textTransform: "uppercase", color: "rgba(244,244,239,.72)", border: "1px solid rgba(255,255,255,.22)", borderRadius: 999, padding: "5px 10px" }}>{c.status}</span> : null}
          <span style={{ fontFamily: "var(--font-display)", fontSize: 30, lineHeight: 1.05, letterSpacing: "0", color: "var(--paper)" }}>{c.client}</span>
        </div>
      </div>
      <div style={{ padding: "24px 24px 28px" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14 }}>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, lineHeight: 1.4, letterSpacing: ".1em", textTransform: "uppercase", color: "var(--text-muted)" }}>{c.kind}</span>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--text-disabled)" }}>{c.year}</span>
        </div>
        <h3 style={{ fontFamily: "var(--font-sans)", fontWeight: 700, fontSize: 20, lineHeight: 1.25, letterSpacing: "0", margin: "0 0 10px" }}>{c.title}</h3>
        <p style={{ color: "var(--text-muted)", fontSize: 14.5, lineHeight: 1.55, margin: 0 }}>{c.blurb}</p>
      </div>
    </a>
  );
}

function PageHead({ eyebrow, title, sub }) {
  const { Eyebrow } = VW_NS;
  return (
    <div style={{ maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "clamp(48px,7vw,96px) var(--page-margin) 56px" }}>
      <Eyebrow>{eyebrow}</Eyebrow>
      <h1 style={{ fontFamily: "var(--font-display)", fontSize: "clamp(44px,6.5vw,80px)", lineHeight: 1.09, letterSpacing: "0", margin: "30px 0 0", maxWidth: "16ch", textWrap: "balance" }}>{title}</h1>
      {sub ? <p style={{ color: "var(--text-secondary)", fontSize: 19, lineHeight: 1.62, maxWidth: "52ch", margin: "32px 0 0" }}>{sub}</p> : null}
    </div>
  );
}

function PitchMosaic({ slides, tone, hover }) {
  const tiltRef = React.useRef(null);
  const onMove = (e) => {
    const el = tiltRef.current; if (!el) return;
    if (!(window.matchMedia && window.matchMedia("(pointer:fine)").matches)) return;
    const r = el.getBoundingClientRect();
    const rx = ((e.clientY - r.top) / r.height - 0.5) * -8;
    const ry = ((e.clientX - r.left) / r.width - 0.5) * 10;
    el.style.transform = `rotateX(${(hover ? 4 : 14) + rx}deg) rotateZ(${hover ? 0 : -10}deg) rotateY(${ry}deg) scale(${hover ? 1.02 : 1})`;
  };
  const reset = () => { const el = tiltRef.current; if (el) el.style.transform = ""; };
  const pool = slides.concat(slides).slice(0, 9);
  return (
    <div style={{ position: "absolute", inset: 0, perspective: "1200px", overflow: "hidden" }} onMouseMove={onMove} onMouseLeave={reset}>
      <div ref={tiltRef} style={{ position: "absolute", inset: "-16%", display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gridAutoRows: "1fr", gap: "clamp(8px,1.2vw,16px)", transformStyle: "preserve-3d", transform: hover ? "rotateX(4deg) rotateZ(0deg) scale(1.02)" : "rotateX(14deg) rotateZ(-10deg)", transition: "transform .7s cubic-bezier(.16,1,.3,1)", willChange: "transform" }}>
        {pool.map((img, k) => (
          <div key={k} style={{ position: "relative", borderRadius: 6, overflow: "hidden", border: "1px solid rgba(255,255,255,.14)", boxShadow: "0 20px 40px -22px rgba(0,0,0,.6)", transform: `translateZ(${hover ? (k % 3) * 26 + 8 : 0}px)`, transition: "transform .7s cubic-bezier(.16,1,.3,1)" }}>
            <img src={"assets/work/" + img} alt="" draggable="false" loading="lazy" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }} />
          </div>
        ))}
      </div>
    </div>
  );
}

function RotateThumb({ imgs, hover }) {
  const [i, setI] = React.useState(0);
  React.useEffect(() => {
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
    const t = setInterval(() => setI(p => (p + 1) % imgs.length), 2600);
    return () => clearInterval(t);
  }, [imgs.length]);
  return (
    <div style={{ position: "absolute", inset: 0, overflow: "hidden" }}>
      {imgs.map((img, k) => (
        <img key={img} src={"assets/work/" + img} alt="" draggable="false" loading={k === 0 ? "eager" : "lazy"}
          style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", objectPosition: "center", opacity: k === i ? 1 : 0, transform: `scale(${(hover ? 1.05 : 1) * (k === i ? 1 : 1.04)})`, transition: "opacity 1s ease, transform 1.4s cubic-bezier(.16,1,.3,1)" }} />
      ))}
      <div style={{ position: "absolute", right: "clamp(16px,1.6vw,24px)", bottom: "clamp(16px,1.6vw,24px)", zIndex: 3, display: "flex", gap: 6 }}>
        {imgs.map((img, k) => (
          <span key={img} style={{ width: k === i ? 16 : 6, height: 6, borderRadius: 999, background: k === i ? "var(--lime-500)" : "rgba(244,244,239,.4)", transition: "all .4s cubic-bezier(.16,1,.3,1)" }} />
        ))}
      </div>
    </div>
  );
}

function CaseRow({ c, i, onOpen }) {
  const { Button } = VW_NS;
  const flip = i % 2 === 1;
  const [hover, setHover] = React.useState(false);
  return (
    <div style={{ display: "grid", gridTemplateColumns: "1.06fr 0.94fr", gap: "clamp(32px,4.5vw,80px)", alignItems: "center", padding: "clamp(40px,5.5vw,88px) 0", borderTop: "1px solid var(--border-default)" }}>
      {/* visual */}
      <a href="#" onClick={(e) => { e.preventDefault(); onOpen(); }} onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
        style={{ order: flip ? 2 : 1, display: "block", textDecoration: "none" }}>
        <div style={{ position: "relative", aspectRatio: "16 / 10", borderRadius: "var(--radius-lg)", overflow: "hidden", background: `linear-gradient(150deg, ${c.tone}, #0b0b0d)`, border: "1px solid var(--border-subtle)", boxShadow: hover ? "0 50px 90px -50px rgba(0,0,0,.7)" : "0 30px 60px -50px rgba(0,0,0,.5)", transition: "box-shadow .4s ease" }}>
          {c.deck || c.mosaic ? (
            <PitchMosaic slides={c.deck || c.mosaic} tone={c.tone} hover={hover} />
          ) : c.rotate ? (
            <RotateThumb imgs={c.rotate} hover={hover} />
          ) : c.img ? (
            <img src={c.img} alt={c.client + " — " + c.title} style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", objectPosition: "center", transform: `scale(${(c.imgScale || 1.35) * (hover ? 1.04 : 1)})`, transformOrigin: "center", transition: "transform .6s cubic-bezier(.16,1,.3,1)" }} />
          ) : (
            <React.Fragment>
              <div style={{ position: "absolute", inset: 0, backgroundImage: "linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px)", backgroundSize: "clamp(40px,3.6vw,58px) clamp(40px,3.6vw,58px)", opacity: .55 }} />
              <span aria-hidden="true" style={{ position: "absolute", right: "5%", bottom: "-12%", fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(140px,20vw,300px)", lineHeight: .8, color: "transparent", WebkitTextStroke: "1.4px rgba(244,244,239,.14)", textStroke: "1.4px rgba(244,244,239,.14)" }}>{c.fig}</span>
              <img src="assets/logos/deckhaus-mark-lime.svg" style={{ position: "absolute", left: "6%", top: "50%", transform: "translateY(-50%)", height: "40%", opacity: .42 }} alt="" />
            </React.Fragment>
          )}
          {c.deck || c.mosaic ? <div aria-hidden="true" style={{ position: "absolute", inset: 0, pointerEvents: "none", background: "radial-gradient(120% 90% at 50% 44%, transparent 46%, rgba(10,10,11,.5))" }} /> : null}
          <span style={{ position: "absolute", left: "clamp(18px,1.8vw,26px)", top: "clamp(16px,1.6vw,24px)", zIndex: 2, fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".22em", textTransform: "uppercase", color: "rgba(244,244,239,.6)", mixBlendMode: c.img && !c.deck && !c.mosaic && !c.rotate ? "difference" : "normal" }}>Fig. {c.fig}</span>
          {c.status ? <span style={{ position: "absolute", left: "clamp(18px,1.8vw,26px)", bottom: "clamp(16px,1.6vw,24px)", zIndex: 2, fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: ".14em", textTransform: "uppercase", color: "rgba(244,244,239,.82)", border: "1px solid rgba(255,255,255,.24)", borderRadius: 999, padding: "5px 11px", backdropFilter: "blur(4px)" }}>{c.status}</span> : null}
        </div>
      </a>
      {/* text */}
      <div style={{ order: flip ? 1 : 2 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <span style={{ width: 18, height: 2, background: "var(--lime-500)", flex: "none" }} />
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".16em", textTransform: "uppercase", color: "var(--text-accent)" }}>{String(i + 1).padStart(2, "0")} · {c.sector}</span>
          <span style={{ flex: 1, height: 1, background: "var(--border-default)" }} />
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 12.5, letterSpacing: ".06em", color: "var(--text-muted)" }}>{c.year}</span>
        </div>
        <h2 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(30px,3.6vw,52px)", lineHeight: 1.06, letterSpacing: "-0.01em", margin: "clamp(20px,2vw,30px) 0 0", textWrap: "balance" }}>{c.client} <span style={{ color: "var(--text-muted)" }}>— {c.title}</span></h2>
        <p style={{ fontFamily: "var(--font-sans)", fontSize: 17, lineHeight: 1.64, color: "var(--text-secondary)", margin: "clamp(16px,1.6vw,22px) 0 0", maxWidth: "50ch" }}>{c.blurb}</p>
        <div style={{ marginTop: "clamp(24px,2.4vw,32px)" }}>
          <Button variant="ghost" onClick={onOpen} trailingIcon={<window.ArrowR/>}>View case study</Button>
        </div>
      </div>
    </div>
  );
}

function WorkView() {
  const { Button } = VW_NS;
  const cases = window.DH_DATA.cases;
  return (
    <main>
      <PageHead eyebrow="Selected work" title="Case studies." sub="A view into how the Visual Sprint turns briefings into presentation-ready systems." />
      <section style={{ maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "0 var(--page-margin) var(--section-y)" }}>
        {cases.map((c, i) => <CaseRow key={c.client} c={c} i={i} onOpen={() => window.DH_NAV("case", c.slug)} />)}
        <div style={{ borderTop: "1px solid var(--border-default)", paddingTop: "clamp(40px,5vw,72px)", display: "flex", justifyContent: "space-between", alignItems: "center", gap: 24, flexWrap: "wrap" }}>
          <p style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(22px,2.4vw,32px)", lineHeight: 1.2, letterSpacing: "-0.01em", margin: 0, maxWidth: "20ch" }}>More work shared on request — under NDA until launch.</p>
          <Button onClick={() => window.DH_NAV("contact")} trailingIcon={<window.ArrowR/>}>Start a project</Button>
        </div>
      </section>
    </main>
  );
}

// Mini rotating cover reel — a slim horizontal capsule; pieces are cropped (Slidor-style)
function WinReel({ imgs, pos }) {
  const [i, setI] = React.useState(0);
  React.useEffect(() => {
    if (!imgs || imgs.length < 2) return;
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
    const t = setInterval(() => setI(p => (p + 1) % imgs.length), 1500);
    return () => clearInterval(t);
  }, [imgs]);
  return (
    <div style={{ position: "relative", width: "100%", height: "clamp(58px,5.4vw,74px)", borderRadius: 999, overflow: "hidden", background: "#EAE6DE", border: "1px solid var(--border-subtle)", boxShadow: "0 18px 34px -24px rgba(10,10,11,.28), 0 2px 8px -6px rgba(10,10,11,.14)" }}>
      {(imgs || []).map((src, k) => (
        <img key={src} src={src} alt="" draggable="false" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", objectPosition: pos, opacity: k === i ? 1 : 0, transition: "opacity .7s ease" }} />
      ))}
    </div>
  );
}

function PillarRow({ l, i, includes, benefit }) {
  const ref = React.useRef(null);
  const glowRef = React.useRef(null);
  const onMove = (e) => {
    const el = ref.current, g = glowRef.current; if (!el || !g) return;
    if (!(window.matchMedia && window.matchMedia("(pointer:fine)").matches)) return;
    const r = el.getBoundingClientRect();
    g.style.setProperty("--gx", (e.clientX - r.left) + "px");
    g.style.setProperty("--gy", (e.clientY - r.top) + "px");
  };
  const enter = () => { const el = ref.current, g = glowRef.current; if (g) g.style.opacity = "1"; if (el) el.style.borderTopColor = "var(--lime-500)"; };
  const leave = () => { const el = ref.current, g = glowRef.current; if (g) g.style.opacity = "0"; if (el) el.style.borderTopColor = "var(--border-default)"; };
  // mini "window" preview — a rotating reel of real sample pieces per pillar
  const preview = {
    "Strategic Presentations": { tag: "Pitch deck", label: "Presentation covers", pos: "center", imgs: ["assets/work/covers/paris-masters.png", "assets/work/covers/michelin.png", "assets/work/covers/tedx.png", "assets/work/covers/moncler.png", "assets/work/covers/rolex-daytona.png", "assets/work/covers/preventive.png"] },
    "Content Systems": { tag: "Content system", label: "Content pieces", pos: "center top", imgs: ["assets/work/content-systems/mango.png", "assets/work/content-systems/on.png", "assets/work/content-systems/rolex.png"] },
    "Brand Experiences": { tag: "Event", label: "Event moments", pos: "center", imgs: ["assets/work/lacoste/ev-photocall.png", "assets/work/lacoste/ev-cocktail2.png", "assets/work/lacoste/merch.png", "assets/work/lacoste/ev-stage.png", "assets/work/lacoste/badges.png", "assets/work/lacoste/moodboard.png"] },
  };
  const pv = preview[l.title] || preview["Strategic Presentations"];
  return (
    <div ref={ref} onMouseMove={onMove} onMouseEnter={enter} onMouseLeave={leave}
      style={{ position: "relative", display: "grid", gridTemplateColumns: "0.9fr 1.1fr", gap: "clamp(32px,5vw,88px)", padding: "clamp(44px,5.5vw,80px) clamp(20px,2.4vw,40px)", marginInline: "clamp(-20px,-2.4vw,-40px)", borderTop: "1px solid var(--border-default)", alignItems: "start", borderRadius: "var(--radius-lg)", transition: "border-color .4s" }}>
      <div aria-hidden="true" style={{ position: "absolute", inset: 0, overflow: "hidden", borderRadius: "var(--radius-lg)", pointerEvents: "none" }}>
        <div ref={glowRef} style={{ position: "absolute", inset: 0, opacity: 0, transition: "opacity .45s ease", background: "radial-gradient(340px 340px at var(--gx,50%) var(--gy,0%), rgba(183,201,74,.20), rgba(183,201,74,.05) 45%, transparent 70%)" }} />
      </div>
      <div style={{ position: "sticky", top: 100, zIndex: 1 }}>
        <div style={{ display: "flex", alignItems: "baseline", gap: 18 }}>
          <span style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(48px,5vw,80px)", lineHeight: .82, letterSpacing: "-0.02em", color: "transparent", WebkitTextStroke: "1.4px rgba(10,10,11,.24)" }}>{String(i + 1).padStart(2, "0")}</span>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--text-muted)" }}>{i === 0 ? "Core practice" : l.scale}</span>
        </div>
        <h2 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(34px,4vw,56px)", lineHeight: 1.04, letterSpacing: "-0.015em", margin: "clamp(22px,2.4vw,32px) 0 0", maxWidth: "13ch" }}>{benefit}</h2>
        <div style={{ display: "inline-flex", alignItems: "center", gap: 10, marginTop: 20 }}>
          <span style={{ width: 22, height: 2, background: "var(--lime-500)" }} />
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--text-accent)" }}>{l.title}</span>
        </div>
        <figure className="dh-svc-win" style={{ margin: "clamp(28px,3vw,40px) 0 0", width: "min(100%, 300px)" }}>
          <WinReel imgs={pv.imgs} pos={pv.pos} />
          <figcaption style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 13, paddingLeft: 4, fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: ".1em", textTransform: "uppercase", color: "var(--text-muted)" }}>
            <span style={{ width: 14, height: 1, background: "var(--lime-500)" }} />
            {pv.label}
          </figcaption>
        </figure>
      </div>
      <div style={{ position: "relative", zIndex: 1, paddingTop: 6 }}>
        <p style={{ fontFamily: "var(--font-sans)", fontSize: "clamp(17px,1.4vw,21px)", lineHeight: 1.58, color: "var(--text-secondary)", margin: 0, maxWidth: "44ch" }}>{l.desc}</p>
        <div style={{ marginTop: "clamp(28px,3vw,40px)" }}>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".16em", textTransform: "uppercase", color: "var(--text-muted)" }}>What's included</span>
          <div style={{ marginTop: 16, borderTop: "1px solid var(--border-default)" }}>
            {includes[l.title].map((it, k) => (
              <div key={it} style={{ display: "grid", gridTemplateColumns: "34px 1fr", gap: 14, alignItems: "baseline", padding: "15px 0", borderBottom: "1px solid var(--border-subtle)" }}>
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--text-muted)" }}>{String(k + 1).padStart(2, "0")}</span>
                <span style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(18px,1.7vw,23px)", lineHeight: 1.2, letterSpacing: "-0.01em", color: "var(--text-primary)" }}>{it}</span>
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

function ServicesView() {
  const { Eyebrow, Button } = VW_NS;
  const D = window.DH_DATA;
  // The 8 detailed offerings, mapped under the 3 strategic pillars
  const includes = {
    "Strategic Presentations": ["Sales & pitch decks", "Executive presentations", "Corporate reports", "PowerPoint template systems"],
    "Content Systems": ["LinkedIn carousels", "Campaign & social templates", "Monthly visual production", "Reusable content libraries"],
    "Brand Experiences": ["Visual identities", "Launches & activations", "Event & screen design", "Digital brand moments"],
  };
  const pillarLine = {
    "Strategic Presentations": "Win the room.",
    "Content Systems": "Stay unmistakable.",
    "Brand Experiences": "Own the moment.",
  };
  // Hero triptych — one art-directed panel per scale
  const PresPanel = () => (
    <div style={{ position: "absolute", inset: 0, background: "#F4F0E7", containerType: "size" }}>
      <div aria-hidden="true" style={{ position: "absolute", inset: 0, background: "radial-gradient(130% 120% at 50% -10%, rgba(255,255,255,.5), transparent 45%)" }} />
      <span aria-hidden="true" style={{ position: "absolute", left: 0, top: 0, bottom: 0, width: "1.6cqw", background: "var(--lime-500)" }} />
      <div style={{ position: "absolute", inset: 0, padding: "9cqw", display: "flex", flexDirection: "column", color: "#17140D" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: "3cqw", letterSpacing: ".24em", textTransform: "uppercase", color: "rgba(0,0,0,.4)" }}>Deckhaus</span>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: "3cqw", letterSpacing: ".2em", color: "rgba(0,0,0,.4)" }}>01</span>
        </div>
        <div style={{ marginTop: "auto", fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "16cqw", lineHeight: .94, letterSpacing: "-0.02em" }}>The Growth<br/>Plan<span style={{ color: "var(--lime-500)" }}>.</span></div>
        <div style={{ display: "flex", alignItems: "flex-end", gap: "4cqw", marginTop: "7cqw", height: "22cqw" }}>
          {[0.5, 0.74, 0.6, 1].map((h, i) => <div key={i} style={{ flex: 1, height: (h * 100) + "%", background: i === 3 ? "var(--lime-500)" : "#17140D" }} />)}
        </div>
      </div>
    </div>
  );
  const EventReel = () => {
    const SHOTS = ["assets/work/lacoste-court-hero.jpg?v=3", "assets/work/lacoste/ev-photocall.png?v=3", "assets/work/lacoste/ev-cocktail2.png?v=3", "assets/work/lacoste/merch.png?v=3", "assets/work/lacoste/ev-cocktail.png?v=3", "assets/work/lacoste/badges.png?v=3", "assets/work/lacoste/moodboard.png?v=3"];
    const [ri, setRi] = React.useState(0);
    React.useEffect(() => {
      if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
      const t = setInterval(() => setRi(p => (p + 1) % SHOTS.length), 2000);
      return () => clearInterval(t);
    }, []);
    return (
      <div style={{ position: "absolute", inset: 0, overflow: "hidden", background: "#0b0f0c" }}>
        {SHOTS.map((s, k) => (
          <img key={s} src={s} alt="" draggable="false" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", objectPosition: "center", opacity: k === ri ? 1 : 0, transform: k === ri ? "scale(1.06)" : "scale(1.14)", transition: "opacity 1s ease-in-out, transform 2.4s ease-out" }} />
        ))}
      </div>
    );
  };
  const PresReel = () => {
    const COLS = [
      ["jura.png", "paris-masters.png", "michelin.png", "tedx.png"],
      ["preventive.png", "america-cup.png", "rolex-daytona.png", "moncler.png"],
    ];
    return (
      <div style={{ position: "absolute", inset: 0, overflow: "hidden", background: "radial-gradient(120% 90% at 60% 30%, #12161d, #08090c 74%)" }}>
        <div aria-hidden="true" style={{ position: "absolute", inset: 0, backgroundImage: "linear-gradient(rgba(255,255,255,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px)", backgroundSize: "38px 38px", opacity: .5 }} />
        <div style={{ position: "absolute", top: "-28%", bottom: "-28%", left: "6%", right: "-14%", display: "flex", gap: "clamp(8px,1vw,14px)", transform: "rotate(-14deg) scale(1.08)", transformOrigin: "center" }}>
          {COLS.map((col, ci) => {
            const pool = col.concat(col);
            return (
              <div key={ci} style={{ flex: 1, display: "flex", flexDirection: "column", gap: "clamp(8px,1vw,14px)", animation: `dh-pcol-${ci === 1 ? "up" : "down"} ${26 + ci * 6}s linear infinite`, marginTop: ci === 1 ? "-12%" : "0" }}>
                {pool.map((src, k) => (
                  <div key={k} style={{ borderRadius: 8, overflow: "hidden", border: "1px solid rgba(255,255,255,.12)", boxShadow: "0 24px 44px -24px rgba(0,0,0,.7)", flex: "none" }}>
                    <img src={"assets/work/covers/" + src} alt="" draggable="false" style={{ display: "block", width: "100%", height: "auto" }} />
                  </div>
                ))}
              </div>
            );
          })}
        </div>
        <div aria-hidden="true" style={{ position: "absolute", inset: 0, background: "radial-gradient(120% 80% at 50% 50%, transparent 55%, rgba(8,9,12,.6))", pointerEvents: "none" }} />
      </div>
    );
  };
  const ContentReel = () => {
    const SHOTS = ["assets/work/content-systems/mango.png", "assets/work/content-systems/on.png", "assets/work/content-systems/rolex.png"];
    const [ri, setRi] = React.useState(0);
    React.useEffect(() => {
      if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
      const t = setInterval(() => setRi(p => (p + 1) % SHOTS.length), 2400);
      return () => clearInterval(t);
    }, []);
    return (
      <div style={{ position: "absolute", inset: 0, overflow: "hidden", background: "#0d0e10" }}>
        {SHOTS.map((s, k) => (
          <img key={s} src={s} alt="" draggable="false" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", objectPosition: "center", opacity: k === ri ? 1 : 0, transform: k === ri ? "scale(1.05)" : "scale(1.12)", transition: "opacity 1s ease-in-out, transform 2.6s ease-out" }} />
        ))}
      </div>
    );
  };
  const pillars = [
    { title: "Strategic Presentations", panel: <PresReel /> },
    { title: "Content Systems", panel: <ContentReel /> },
    { title: "Brand Experiences", panel: <EventReel /> },
  ];
  return (
    <main>
      {/* PREMIUM HERO — dark, statement + triptych */}
      <section data-theme="dark" style={{ position: "relative", background: "var(--bg-base)", borderBottom: "1px solid var(--border-subtle)", overflow: "hidden" }}>
        <div aria-hidden="true" style={{ position: "absolute", inset: 0, backgroundImage: "linear-gradient(rgba(244,244,239,.045) 1px, transparent 1px), linear-gradient(90deg, rgba(244,244,239,.045) 1px, transparent 1px)", backgroundSize: "54px 54px", pointerEvents: "none", WebkitMaskImage: "radial-gradient(120% 80% at 80% 0%, #000 15%, transparent 68%)", maskImage: "radial-gradient(120% 80% at 80% 0%, #000 15%, transparent 68%)" }} />
        <div style={{ position: "relative", maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "clamp(52px,7vw,104px) var(--page-margin) 0" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", flexWrap: "wrap", gap: 16 }}>
            <Eyebrow>What we do</Eyebrow>
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".16em", textTransform: "uppercase", color: "var(--text-muted)" }}>Services · 03</span>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1.25fr 0.75fr", gap: "clamp(28px,4vw,72px)", alignItems: "end", marginTop: "clamp(22px,2.4vw,34px)" }}>
            <h1 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(48px,7.4vw,104px)", lineHeight: 1.0, letterSpacing: "-0.02em", margin: 0, textWrap: "balance" }}>Three scales of <span style={{ color: "var(--lime-500)" }}>one idea.</span></h1>
            <p style={{ color: "var(--text-secondary)", fontSize: "clamp(16px,1.3vw,19px)", lineHeight: 1.6, margin: 0, maxWidth: "44ch" }}>Not three markets — three scales of the same problem: how a brand shows up, stays clear, and becomes unforgettable in the room.</p>
          </div>
          {/* triptych */}
          <div className="dh-mstack" style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: "clamp(12px,1.4vw,20px)", margin: "clamp(40px,5vw,72px) 0 0", transform: "translateY(1px)" }}>
            {pillars.map((p, i) => (
              <div key={p.title} style={{ position: "relative", aspectRatio: "3 / 4", borderRadius: "var(--radius-lg) var(--radius-lg) 0 0", overflow: "hidden", border: "1px solid var(--border-default)", borderBottom: "none", background: "#0b0f0c" }}>
                {p.panel ? p.panel : <img src={p.img} alt={p.title} style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", transform: `scale(${p.scale})` }} />}
                <div style={{ position: "absolute", inset: 0, background: "linear-gradient(to top, rgba(8,10,8,.9) 6%, rgba(8,10,8,.05) 46%)" }} />
                <div style={{ position: "absolute", left: "clamp(16px,1.6vw,24px)", top: "clamp(14px,1.4vw,22px)", fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".16em", color: "var(--lime-500)" }}>{String(i + 1).padStart(2, "0")}</div>
                <div style={{ position: "absolute", left: "clamp(16px,1.6vw,24px)", right: "clamp(16px,1.6vw,24px)", bottom: "clamp(18px,1.8vw,26px)" }}>
                  <div style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(19px,1.8vw,26px)", lineHeight: 1.08, letterSpacing: "-0.01em", color: "var(--paper)" }}>{p.title}</div>
                  <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".12em", textTransform: "uppercase", color: "rgba(244,244,239,.6)", marginTop: 8 }}>{pillarLine[p.title]}</div>
                </div>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* detailed pillars — editorial */}
      <section style={{ maxWidth: "var(--maxw-content)", margin: "0 auto", padding: "clamp(48px,6vw,88px) var(--page-margin) 0" }}>
        {D.lines.map((l, i) => (
          <PillarRow key={l.title} l={l} i={i} includes={includes} benefit={pillarLine[l.title]} />
        ))}
      </section>

      {/* one idea — closing statement */}
      <section style={{ borderTop: "1px solid var(--border-default)", marginTop: "clamp(48px,6vw,88px)" }}>
        <div style={{ maxWidth: "var(--maxw-content)", margin: "0 auto", padding: "var(--section-y) var(--page-margin)", display: "grid", gridTemplateColumns: "1fr auto", gap: "clamp(28px,4vw,64px)", alignItems: "end" }}>
          <div>
            <Eyebrow>One idea</Eyebrow>
            <p style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(26px,3.2vw,46px)", lineHeight: 1.14, letterSpacing: "-0.01em", margin: "clamp(20px,2vw,28px) 0 0", maxWidth: "20ch", textWrap: "balance" }}>Different scales, <span style={{ fontStyle: "italic", color: "var(--text-accent)" }}>one</span> visual language across all of them.</p>
          </div>
          <Button size="lg" onClick={() => window.DH_NAV("contact")} trailingIcon={<window.ArrowR/>}>Start a project</Button>
        </div>
      </section>
    </main>
  );
}

function Sprint45() {
  const ref = React.useRef(null);
  const [p, setP] = React.useState(0);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) { setP(1); return; }
    let raf = null, started = false; const dur = 2200;
    const io = new IntersectionObserver((es) => es.forEach(e => {
      if (e.isIntersecting && !started) { started = true; const t0 = performance.now();
        const step = (t) => { const x = Math.min(1, (t - t0) / dur); setP(1 - Math.pow(1 - x, 4)); if (x < 1) raf = requestAnimationFrame(step); };
        raf = requestAnimationFrame(step); io.disconnect();
      }
    }), { threshold: 0.6 });
    io.observe(el); return () => { io.disconnect(); if (raf) cancelAnimationFrame(raf); };
  }, []);
  return (
    <div ref={ref} style={{ marginTop: "clamp(28px,3vw,40px)" }}>
      <div style={{ display: "flex", alignItems: "flex-end", gap: 6 }}>
        <span style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(56px,8vw,110px)", lineHeight: .82, letterSpacing: "-0.02em", color: "var(--text-primary)" }}>{Math.round(p * 45)}</span>
        <span style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(30px,4vw,60px)", lineHeight: .9, color: "var(--lime-500)" }}>%</span>
      </div>
      <div style={{ position: "relative", height: 8, background: "rgba(10,10,11,.1)", borderRadius: 999, marginTop: 18, overflow: "hidden" }}>
        <div style={{ position: "absolute", left: 0, top: 0, bottom: 0, width: (p * 45) + "%", background: "var(--lime-500)", borderRadius: 999 }} />
      </div>
      <span style={{ display: "block", fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".08em", color: "var(--text-muted)", marginTop: 14, maxWidth: "34ch" }}>of the potential, shipped — the rest lost to guesswork and rework.</span>
    </div>
  );
}

function SprintDirections() {
  // exploration → convergence: many strong routes, one chosen
  const routes = [
    { bg: "#12161A", ink: "#EAF0F5", accent: "#4C8DFF" },
    { bg: "#1A130E", ink: "#F3E7D8", accent: "#C98A3F" },
    { bg: "#0F1712", ink: "#E7F3E9", accent: "#39B37A" },
    { bg: "#1A0E13", ink: "#F5E3EA", accent: "#E0537B" },
  ];
  const [pick, setPick] = React.useState(2);
  React.useEffect(() => { const t = setInterval(() => setPick(p => (p + 1) % routes.length), 1800); return () => clearInterval(t); }, []);
  return (
    <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: "clamp(12px,1.4vw,20px)" }}>
      {routes.map((r, i) => {
        const on = i === pick;
        return (
          <div key={i} onMouseEnter={() => setPick(i)} style={{ position: "relative", aspectRatio: "4 / 5", borderRadius: "var(--radius-md)", overflow: "hidden", background: r.bg, border: `1px solid ${on ? "var(--lime-500)" : "rgba(244,244,239,.14)"}`, transform: on ? "translateY(-6px)" : "none", boxShadow: on ? "0 30px 60px -30px rgba(183,201,74,.45)" : "none", transition: "all .5s cubic-bezier(.16,1,.3,1)", cursor: "pointer" }}>
            <div style={{ position: "absolute", inset: 0, padding: "clamp(12px,1.4vw,18px)", display: "flex", flexDirection: "column" }}>
              <span style={{ width: 16, height: 16, borderRadius: "50%", border: `1.4px solid ${r.accent}`, flex: "none" }} />
              <div style={{ marginTop: "auto" }}>
                <div style={{ height: 6, width: "70%", background: r.ink, opacity: .9, borderRadius: 2 }} />
                <div style={{ height: 6, width: "48%", background: r.ink, opacity: .5, borderRadius: 2, marginTop: 6 }} />
                <div style={{ height: 6, width: "30%", background: r.accent, borderRadius: 2, marginTop: 10 }} />
              </div>
            </div>
            <div style={{ position: "absolute", top: 10, right: 10, fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: ".1em", color: on ? "var(--lime-500)" : "rgba(244,244,239,.4)", transition: "color .3s" }}>{on ? "✓ ROUTE" : String.fromCharCode(65 + i)}</div>
          </div>
        );
      })}
    </div>
  );
}

function SprintMethodVisual({ i }) {
  const LN = "rgba(244,244,239,.28)", LNs = "rgba(244,244,239,.14)", LIME = "var(--lime-500)";
  const box = { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", padding: "clamp(24px,4vw,52px)" };
  if (i === 0) return (
    <div style={box}><div style={{ width: "62%", maxWidth: 300, background: "#F4F0E7", borderRadius: 6, padding: "clamp(18px,2vw,26px)", boxShadow: "0 30px 60px -34px rgba(0,0,0,.7)" }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", borderBottom: "1px solid rgba(0,0,0,.1)", paddingBottom: 12 }}><span style={{ fontFamily: "var(--font-mono)", fontSize: 9, letterSpacing: ".16em", color: "rgba(0,0,0,.4)" }}>BRIEF</span><span style={{ width: 20, height: 6, background: LIME, borderRadius: 2 }} /></div>
      {[0.9, 0.7, 0.8, 0.5].map((w, k) => <div key={k} style={{ height: 6, width: (w * 100) + "%", background: k === 0 ? "rgba(0,0,0,.6)" : "rgba(0,0,0,.18)", borderRadius: 2, marginTop: 12 }} />)}
    </div></div>
  );
  if (i === 1) return (
    <div style={box}><div style={{ width: "70%", maxWidth: 320, background: "#0c0f14", border: "1px solid rgba(244,244,239,.14)", borderRadius: 6, padding: "clamp(18px,2vw,26px)", fontFamily: "var(--font-mono)" }}>
      <div style={{ fontSize: 10, letterSpacing: ".14em", color: LIME, marginBottom: 14 }}>PROMPT</div>
      {["tone: premium, editorial", "light: soft, directional", "mood: confident, calm"].map((t, k) => <div key={t} style={{ fontSize: 12, color: "rgba(244,244,239,.7)", marginTop: 8 }}>{t}{k === 2 ? <span className="dh-reel-fill" style={{ display: "inline-block", width: 7, height: 13, background: LIME, marginLeft: 4, verticalAlign: "-2px" }} /> : null}</div>)}
    </div></div>
  );
  if (i === 2) return (
    <div style={box}><div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 10, width: "100%", maxWidth: 360 }}>
      {["#4C8DFF", "#C98A3F", "#39B37A", "#E0537B"].map((c, k) => (
        <div key={c} style={{ aspectRatio: "3/4", borderRadius: 4, background: "#0c0f14", border: `1px solid ${k === 2 ? LIME : "rgba(244,244,239,.16)"}`, transform: k === 2 ? "translateY(-8px)" : "none", boxShadow: k === 2 ? "0 20px 36px -20px rgba(183,201,74,.5)" : "none", transition: "all .4s", padding: 8, display: "flex", flexDirection: "column", justifyContent: "flex-end" }}>
          <span style={{ width: 12, height: 12, borderRadius: "50%", border: `1.4px solid ${c}`, alignSelf: "flex-start" }} />
          <div style={{ height: 4, width: "70%", background: c, borderRadius: 2, marginTop: "auto" }} />
        </div>
      ))}
    </div></div>
  );
  if (i === 3) return (
    <div style={box}><div style={{ position: "relative", width: "58%", maxWidth: 260, aspectRatio: "4/5", borderRadius: 6, background: "#0c0f14", border: `1.5px solid ${LIME}`, boxShadow: "0 30px 60px -30px rgba(183,201,74,.5)", padding: 18, display: "flex", flexDirection: "column", justifyContent: "flex-end" }}>
      <span style={{ position: "absolute", top: 14, right: 14, width: 26, height: 26, borderRadius: "50%", background: LIME, color: "#0A0A0B", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 15, fontWeight: 700 }}>✓</span>
      <div style={{ fontFamily: "var(--font-display)", fontSize: 26, color: "#F4F4EF", lineHeight: 1 }}>Aa</div>
      <div style={{ height: 4, width: "60%", background: LIME, borderRadius: 2, marginTop: 12 }} />
      <div style={{ height: 4, width: "40%", background: "rgba(244,244,239,.3)", borderRadius: 2, marginTop: 6 }} />
    </div></div>
  );
  return (
    <div style={box}><div style={{ width: "72%", maxWidth: 340, aspectRatio: "16/10", borderRadius: 6, background: "#F4F0E7", boxShadow: "0 34px 64px -32px rgba(0,0,0,.75)", padding: "clamp(16px,2vw,24px)", display: "flex", flexDirection: "column", position: "relative", overflow: "hidden" }}>
      <span style={{ position: "absolute", left: 0, top: 0, bottom: 0, width: 5, background: LIME }} />
      <span style={{ fontFamily: "var(--font-mono)", fontSize: 8.5, letterSpacing: ".2em", color: "rgba(0,0,0,.4)" }}>DECKHAUS</span>
      <div style={{ marginTop: "auto", fontFamily: "var(--font-display)", fontSize: "clamp(22px,3vw,34px)", lineHeight: .95, letterSpacing: "-0.02em", color: "#17140D" }}>The Growth<br/>Plan<span style={{ color: LIME }}>.</span></div>
    </div></div>
  );
}

function SprintMethod({ phases }) {
  const [active, setActive] = React.useState(0);
  const [paused, setPaused] = React.useState(false);
  const DUR = 3400;
  React.useEffect(() => {
    if (paused) return;
    const t = setInterval(() => setActive(a => (a + 1) % phases.length), DUR);
    return () => clearInterval(t);
  }, [paused, phases.length]);
  const p = phases[active];
  return (
    <div onMouseEnter={() => setPaused(true)} onMouseLeave={() => setPaused(false)}>
      {/* tab rail */}
      <div style={{ display: "grid", gridTemplateColumns: `repeat(${phases.length}, 1fr)`, gap: "clamp(6px,1vw,14px)" }}>
        {phases.map((ph, i) => {
          const on = i === active, done = i < active;
          return (
            <button key={ph.n} onClick={() => setActive(i)} aria-label={ph.t}
              style={{ all: "unset", boxSizing: "border-box", cursor: "pointer", paddingTop: 14, borderTop: `2px solid ${on ? "var(--lime-500)" : done ? "rgba(183,201,74,.4)" : "rgba(244,244,239,.16)"}`, transition: "border-color .35s" }}>
              <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: on ? "var(--lime-500)" : "var(--text-muted)", transition: "color .3s" }}>{ph.n}</span>
                {on ? <span style={{ flex: 1, height: 2, background: "rgba(183,201,74,.2)", overflow: "hidden" }}><span key={active} className="dh-method-fill" style={{ display: "block", height: "100%", width: "100%", background: "var(--lime-500)", transformOrigin: "left" }} /></span> : null}
              </div>
              <div style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: ".08em", textTransform: "uppercase", color: on ? "var(--paper)" : "var(--text-muted)", marginTop: 9, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", transition: "color .3s" }}>{ph.t}</div>
            </button>
          );
        })}
      </div>
      {/* panel */}
      <div style={{ display: "grid", gridTemplateColumns: "0.85fr 1.15fr", gap: "clamp(28px,4vw,64px)", alignItems: "center", marginTop: "clamp(32px,4vw,52px)" }}>
        <div key={"t" + active} className="dh-reel-in">
          <span style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(60px,8vw,120px)", lineHeight: .8, letterSpacing: "-0.02em", color: "transparent", WebkitTextStroke: "1.6px rgba(244,244,239,.3)" }}>{p.n}</span>
          <h3 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(28px,3.2vw,44px)", lineHeight: 1.06, letterSpacing: "-0.015em", margin: "clamp(20px,2vw,28px) 0 0", color: "var(--paper)" }}>{p.t}</h3>
          <p style={{ color: "var(--text-secondary)", fontSize: 17, lineHeight: 1.62, margin: "18px 0 0", maxWidth: "42ch" }}>{p.d}</p>
          <span style={{ display: "block", fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--text-muted)", marginTop: 26 }}>Phase {p.n} / 05</span>
        </div>
        <div style={{ position: "relative", aspectRatio: "16 / 10", borderRadius: "var(--radius-lg)", overflow: "hidden", border: "1px solid var(--border-subtle)", background: "linear-gradient(150deg, #131316, #0a0a0c)" }}>
          <div aria-hidden="true" style={{ position: "absolute", inset: 0, backgroundImage: "linear-gradient(rgba(244,244,239,.05) 1px, transparent 1px), linear-gradient(90deg, rgba(244,244,239,.05) 1px, transparent 1px)", backgroundSize: "40px 40px", opacity: .6 }} />
          <div key={"v" + active} className="dh-reel-in" style={{ position: "absolute", inset: 0 }}><SprintMethodVisual i={active} /></div>
        </div>
      </div>
    </div>
  );
}

function SprintDemo() {
  const [open, setOpen] = React.useState(false);
  const BRIEFS = [
    { key: "fintech", label: "A fintech pitch", routes: [
      { name: "Trust", paper: "#0E1320", ink: "#EAF0FA", accent: "#4C8DFF", serif: false, title: "Banking, clarified." },
      { name: "Warm", paper: "#F3EEE3", ink: "#1A1813", accent: "#C98A3F", serif: true, title: "Money, human." },
      { name: "Bold", paper: "#101510", ink: "#EAF7E6", accent: "#B7F23A", serif: false, title: "Move faster." },
      { name: "Editorial", paper: "#F7F4F1", ink: "#141414", accent: "#E0537B", serif: true, title: "The new standard." },
    ] },
    { key: "coffee", label: "A coffee brand", routes: [
      { name: "Craft", paper: "#F1E7D9", ink: "#211710", accent: "#9E6B3F", serif: true, title: "Roasted for the ritual." },
      { name: "Modern", paper: "#0f130f", ink: "#EAF3EA", accent: "#7FB069", serif: false, title: "Everyday, elevated." },
      { name: "Editorial", paper: "#F4F0E7", ink: "#1A1813", accent: "#B0472E", serif: true, title: "A cup with a view." },
      { name: "Minimal", paper: "#EDEDE8", ink: "#161616", accent: "#1F1F1F", serif: false, title: "Just good coffee." },
    ] },
    { key: "event", label: "A brand event", routes: [
      { name: "Sport", paper: "#0A0C0A", ink: "#EAF7E6", accent: "#B7F23A", serif: false, title: "Own the moment." },
      { name: "Luxe", paper: "#11100D", ink: "#F3EEE3", accent: "#B79961", serif: true, title: "An evening to remember." },
      { name: "Neon", paper: "#0b0f1a", ink: "#EAF0FA", accent: "#4C8DFF", serif: false, title: "The night begins." },
      { name: "Classic", paper: "#F7F4F1", ink: "#141414", accent: "#1d5b3a", serif: true, title: "Welcome to the room." },
    ] },
  ];
  const [brief, setBrief] = React.useState(null);
  const [locked, setLocked] = React.useState(null);
  const EASE = "cubic-bezier(.16,1,.3,1)";
  const routes = brief ? BRIEFS.find(b => b.key === brief).routes : [];
  const step = locked != null ? 4 : brief ? 3 : 1;
  const reset = () => { setBrief(null); setLocked(null); };
  const close = () => { setOpen(false); setTimeout(reset, 300); };

  const Slide = ({ r, small }) => (
    <div style={{ position: "relative", width: "100%", aspectRatio: "16/10", borderRadius: small ? 7 : 10, overflow: "hidden", background: r.paper, transition: `background .5s ${EASE}` }}>
      <span style={{ position: "absolute", left: 0, top: 0, bottom: 0, width: small ? 3 : 5, background: r.accent }} />
      <div style={{ position: "absolute", inset: 0, padding: small ? "9px 11px" : "clamp(14px,2vw,22px)", display: "flex", flexDirection: "column" }}>
        <span style={{ fontFamily: "var(--font-mono)", fontSize: small ? 6.5 : 10, letterSpacing: ".16em", textTransform: "uppercase", color: r.ink, opacity: .6 }}>Deckhaus</span>
        <span style={{ marginTop: "auto", fontFamily: r.serif ? "var(--font-display)" : "var(--font-sans)", fontWeight: r.serif ? 400 : 700, fontSize: small ? 13 : "clamp(20px,2.6vw,30px)", lineHeight: 1.02, letterSpacing: "-0.01em", color: r.ink }}>{r.title}</span>
        <div style={{ display: "flex", gap: 4, marginTop: small ? 6 : 12 }}>
          {[0,1,2].map(k => <span key={k} style={{ height: small ? 3 : 5, flex: k === 0 ? 2 : 1, borderRadius: 2, background: k === 0 ? r.accent : r.ink, opacity: k === 0 ? 1 : .2 }} />)}
        </div>
      </div>
    </div>
  );

  return (
    <React.Fragment>
      <button onClick={() => setOpen(true)} style={{ all: "unset", cursor: "pointer", display: "inline-flex", alignItems: "center", gap: 12, fontFamily: "var(--font-sans)", fontWeight: 600, fontSize: 15, color: "var(--ink-900)", background: "var(--lime-500)", borderRadius: 999, padding: "13px 22px" }}>
        Try it — see how it works <span aria-hidden="true">↗</span>
      </button>

      {open ? ReactDOM.createPortal((
        <div role="dialog" aria-modal="true" onClick={close} style={{ position: "fixed", inset: 0, zIndex: 2000, display: "flex", alignItems: "center", justifyContent: "center", padding: "clamp(16px,3vw,40px)", background: "rgba(6,7,9,.72)", backdropFilter: "blur(14px)", WebkitBackdropFilter: "blur(14px)", animation: `dh-demo-fade .3s ${EASE}` }}>
          <div data-theme="dark" onClick={(e) => e.stopPropagation()} style={{ position: "relative", width: "100%", maxWidth: 920, maxHeight: "90vh", overflowY: "auto", background: "linear-gradient(155deg,#161616,#0b0b0d)", border: "1px solid rgba(244,244,239,.14)", borderRadius: "var(--radius-xl)", boxShadow: "0 60px 130px -40px rgba(0,0,0,.8)", animation: `dh-demo-pop .4s ${EASE}` }}>
            {/* header */}
            <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16, padding: "clamp(20px,2.4vw,30px) clamp(22px,2.6vw,34px)", borderBottom: "1px solid rgba(244,244,239,.1)" }}>
              <div>
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".2em", textTransform: "uppercase", color: "var(--lime-500)" }}>Visual Sprint · interactive demo</span>
                <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".08em", color: "var(--text-muted)", marginTop: 6 }}>Conceptual · generic example</div>
              </div>
              <button onClick={close} aria-label="Close" style={{ all: "unset", cursor: "pointer", width: 34, height: 34, borderRadius: "50%", border: "1px solid rgba(244,244,239,.2)", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--paper)", fontSize: 16 }}>✕</button>
            </div>
            {/* stepper */}
            <div style={{ display: "flex", gap: 8, padding: "16px clamp(22px,2.6vw,34px) 0" }}>
              {["Brief","Explore","Lock","System"].map((s, k) => (
                <div key={s} style={{ flex: 1, display: "flex", flexDirection: "column", gap: 8 }}>
                  <span style={{ height: 2, background: k < step ? "var(--lime-500)" : "rgba(244,244,239,.14)", transition: `background .4s ${EASE}` }} />
                  <span style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: ".12em", textTransform: "uppercase", color: k < step ? "var(--paper)" : "var(--text-muted)" }}>{String(k+1).padStart(2,"0")} {s}</span>
                </div>
              ))}
            </div>
            {/* body */}
            <div style={{ padding: "clamp(22px,2.6vw,34px)" }}>
              {!brief ? (
                <div>
                  <h3 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(22px,2.4vw,32px)", lineHeight: 1.1, margin: 0, color: "var(--paper)" }}>What are you making?</h3>
                  <p style={{ color: "var(--text-secondary)", fontSize: 15, lineHeight: 1.6, margin: "12px 0 0", maxWidth: "48ch" }}>Pick a brief and watch a Visual Sprint explore directions — then lock the one that feels right.</p>
                  <div style={{ display: "flex", flexWrap: "wrap", gap: 10, marginTop: 24 }}>
                    {BRIEFS.map(b => (
                      <button key={b.key} onClick={() => setBrief(b.key)} style={{ all: "unset", cursor: "pointer", fontFamily: "var(--font-sans)", fontSize: 15, padding: "12px 20px", borderRadius: 999, border: "1px solid rgba(244,244,239,.24)", color: "var(--paper)", transition: `all .2s ${EASE}` }}
                        onMouseEnter={(e) => { e.currentTarget.style.background = "var(--lime-500)"; e.currentTarget.style.color = "var(--ink-900)"; e.currentTarget.style.borderColor = "var(--lime-500)"; }}
                        onMouseLeave={(e) => { e.currentTarget.style.background = "transparent"; e.currentTarget.style.color = "var(--paper)"; e.currentTarget.style.borderColor = "rgba(244,244,239,.24)"; }}>{b.label}</button>
                    ))}
                  </div>
                </div>
              ) : locked == null ? (
                <div>
                  <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, flexWrap: "wrap" }}>
                    <h3 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(20px,2.2vw,28px)", lineHeight: 1.1, margin: 0, color: "var(--paper)" }}>Four directions, explored fast.</h3>
                    <button onClick={reset} style={{ all: "unset", cursor: "pointer", fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".08em", textTransform: "uppercase", color: "var(--text-muted)" }}>← change brief</button>
                  </div>
                  <p style={{ color: "var(--text-secondary)", fontSize: 14.5, lineHeight: 1.6, margin: "10px 0 0" }}>Hover to preview, click to lock the route.</p>
                  <div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: "clamp(10px,1.4vw,16px)", marginTop: 22 }}>
                    {routes.map((r, k) => (
                      <button key={r.name} onClick={() => setLocked(k)} style={{ all: "unset", cursor: "pointer", display: "flex", flexDirection: "column", gap: 8, animation: `dh-demo-rise .5s ${EASE} ${k*0.08}s both` }}>
                        <div style={{ borderRadius: 9, overflow: "hidden", border: "1px solid rgba(244,244,239,.14)", transition: `transform .3s ${EASE}, box-shadow .3s ${EASE}` }}
                          onMouseEnter={(e) => { e.currentTarget.style.transform = "translateY(-4px)"; e.currentTarget.style.boxShadow = "0 22px 40px -22px rgba(183,201,74,.5)"; }}
                          onMouseLeave={(e) => { e.currentTarget.style.transform = "none"; e.currentTarget.style.boxShadow = "none"; }}>
                          <Slide r={r} small />
                        </div>
                        <span style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: ".1em", textTransform: "uppercase", color: "var(--text-muted)" }}>{String(k+1).padStart(2,"0")} · {r.name}</span>
                      </button>
                    ))}
                  </div>
                </div>
              ) : (
                <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "clamp(20px,3vw,44px)", alignItems: "center" }}>
                  <div key={locked} style={{ animation: `dh-demo-pop .5s ${EASE}` }}><Slide r={routes[locked]} /></div>
                  <div>
                    <span style={{ display: "inline-flex", alignItems: "center", gap: 8, fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--lime-500)" }}><span style={{ width: 8, height: 8, borderRadius: "50%", background: "var(--lime-500)" }} />Direction locked</span>
                    <h3 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(24px,2.6vw,36px)", lineHeight: 1.06, margin: "16px 0 0", color: "var(--paper)" }}>Now everything is built on <span style={{ color: "var(--lime-500)" }}>one decision.</span></h3>
                    <p style={{ color: "var(--text-secondary)", fontSize: 15, lineHeight: 1.62, margin: "16px 0 0", maxWidth: "38ch" }}>Deck, campaign, event — all coherent, because the look and feel was agreed before production. That's the Sprint.</p>
                    <div style={{ display: "flex", gap: 12, marginTop: 26, flexWrap: "wrap" }}>
                      <button onClick={() => setLocked(null)} style={{ all: "unset", cursor: "pointer", fontFamily: "var(--font-sans)", fontWeight: 600, fontSize: 14, padding: "11px 18px", borderRadius: 999, border: "1px solid rgba(244,244,239,.24)", color: "var(--paper)" }}>Try another route</button>
                      <button onClick={() => { close(); window.DH_NAV("contact"); }} style={{ all: "unset", cursor: "pointer", fontFamily: "var(--font-sans)", fontWeight: 600, fontSize: 14, padding: "11px 20px", borderRadius: 999, background: "var(--lime-500)", color: "var(--ink-900)" }}>Start your sprint →</button>
                    </div>
                  </div>
                </div>
              )}
            </div>
          </div>
        </div>
      ), document.body) : null}
    </React.Fragment>
  );
}

function SprintView() {
  const { Badge, StatBlock, Eyebrow, Button } = VW_NS;
  const phases = [
    { n: "01", t: "Idea & Briefing", d: "We define the project's goal and visual tone based on the initial briefing." },
    { n: "02", t: "Prompt Design", d: "We translate the concept into strategic prompts that define tone and style." },
    { n: "03", t: "Visual Exploration", d: "AI-assisted exploration tests tone, light and composition early — grounding the concept before we craft." },
    { n: "04", t: "Refine & Craft", d: "In the Direction Room we lock the strongest route, then refine composition and storytelling by hand — alignment before execution." },
    { n: "05", t: "Final Delivery", d: "Final design, ready for presentation or campaign launch." },
  ];
  return (
    <main data-theme="dark" style={{ background: "var(--bg-base)" }}>
      {/* HERO — what is it */}
      <section style={{ position: "relative", borderBottom: "1px solid var(--border-subtle)", overflow: "hidden" }}>
        <div aria-hidden="true" style={{ position: "absolute", inset: 0, backgroundImage: "linear-gradient(rgba(244,244,239,.045) 1px, transparent 1px), linear-gradient(90deg, rgba(244,244,239,.045) 1px, transparent 1px)", backgroundSize: "54px 54px", pointerEvents: "none", WebkitMaskImage: "radial-gradient(120% 80% at 78% 0%, #000 12%, transparent 66%)", maskImage: "radial-gradient(120% 80% at 78% 0%, #000 12%, transparent 66%)" }} />
        <div style={{ position: "relative", maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "clamp(52px,7vw,104px) var(--page-margin)" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 14, flexWrap: "wrap" }}>
            <Badge variant="accent">Visual Sprint™</Badge>
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--text-muted)" }}>What it is · why you need it</span>
          </div>
          <h1 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(46px,7vw,100px)", lineHeight: 1.02, letterSpacing: "-0.02em", margin: "clamp(24px,2.8vw,38px) 0 0", maxWidth: "16ch", textWrap: "balance" }}>
            {[
              { t: "Find" }, { t: "the" }, { t: "right" }, { t: "direction" },
              { t: "before", lime: true }, { t: "you", lime: true }, { t: "build", lime: true }, { t: "everything", lime: true }, { t: "else.", lime: true },
            ].map((w, i) => (
              <React.Fragment key={i}>
                <span className="dh-wm"><span className="dh-wm-in" style={{ animationDelay: (0.08 + i * 0.05) + "s", color: w.lime ? "var(--lime-500)" : undefined }}>{w.t}</span></span>{" "}
              </React.Fragment>
            ))}
          </h1>
          <p className="dh-sv-p" style={{ color: "var(--text-secondary)", fontSize: "clamp(17px,1.5vw,21px)", lineHeight: 1.58, maxWidth: "50ch", margin: "clamp(26px,2.6vw,36px) 0 0" }}>Visual Sprint is how we decide what your communication should look and feel — fast — so everything produced after it is coherent, confident and actually what you pictured.</p>
          <div className="dh-sv-p" style={{ marginTop: "clamp(24px,2.4vw,34px)" }}><SprintDemo /></div>
        </div>
      </section>

      {/* THE PROBLEM — the 45% (light editorial) */}
      <section data-theme="light" style={{ background: "var(--bg-base)", borderBottom: "1px solid var(--border-subtle)" }}>
        <div style={{ maxWidth: "var(--maxw-content)", margin: "0 auto", padding: "var(--section-y) var(--page-margin)" }}>
          <Eyebrow>The problem</Eyebrow>
          <div style={{ display: "grid", gridTemplateColumns: "1.1fr 0.9fr", gap: "clamp(32px,5vw,80px)", alignItems: "center", marginTop: "clamp(28px,3vw,44px)" }}>
            <h2 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(30px,3.8vw,54px)", lineHeight: 1.08, letterSpacing: "-0.015em", margin: 0, maxWidth: "18ch", textWrap: "balance" }}>Everyone wants it <span style={{ fontStyle: "italic" }}>yesterday</span>. Almost nobody has defined what <span style={{ color: "var(--lime-500)" }}>“it”</span> should look like.</h2>
            <div>
              <p style={{ color: "var(--text-secondary)", fontSize: 17, lineHeight: 1.62, margin: 0 }}>So teams rush straight into production with no direction locked — endless revisions, mixed signals, and a result that lands nowhere near what they imagined.</p>
              {/* 45% — number + bar grow together, easing out */}
              <Sprint45 />
            </div>
          </div>
        </div>
      </section>

      {/* WITH VISUAL SPRINT — the payoff numbers */}
      <section data-theme="dark" style={{ position: "relative", background: "linear-gradient(160deg, #16180f 0%, var(--bg-base) 55%)", borderBottom: "1px solid var(--border-subtle)", overflow: "hidden" }}>
        <div aria-hidden="true" style={{ position: "absolute", inset: 0, backgroundImage: "linear-gradient(rgba(183,201,74,.06) 1px, transparent 1px), linear-gradient(90deg, rgba(183,201,74,.06) 1px, transparent 1px)", backgroundSize: "54px 54px", pointerEvents: "none", WebkitMaskImage: "radial-gradient(110% 80% at 12% 0%, #000 15%, transparent 68%)", maskImage: "radial-gradient(110% 80% at 12% 0%, #000 15%, transparent 68%)" }} />
        <div style={{ position: "relative", maxWidth: "var(--maxw-content)", margin: "0 auto", padding: "var(--section-y) var(--page-margin)" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
            <span style={{ width: 22, height: 2, background: "var(--lime-500)", flex: "none" }} />
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".2em", textTransform: "uppercase", color: "var(--lime-500)" }}>With Visual Sprint</span>
          </div>
          <h2 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(28px,3.6vw,50px)", lineHeight: 1.08, letterSpacing: "-0.015em", margin: "clamp(22px,2.4vw,32px) 0 0", maxWidth: "20ch", textWrap: "balance" }}>Direction locked first — so the numbers move the right way.</h2>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: "clamp(20px,2.6vw,48px)", marginTop: "clamp(40px,5vw,72px)" }}>
            {[
              { to: 92, suffix: "%", label: "of the original vision, realised" },
              { to: 70, suffix: "%", label: "less time spent exploring directions" },
              { to: 3, suffix: "×", label: "more strong routes explored, early" },
              { to: 1, suffix: "", label: "locked direction, before production" },
            ].map((s, i) => (
              <div key={i} style={{ borderTop: "1px solid var(--border-subtle)", paddingTop: "clamp(18px,2vw,26px)" }}>
                <div style={{ display: "flex", alignItems: "baseline" }}>
                  <span style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(48px,6.4vw,96px)", lineHeight: .82, letterSpacing: "-0.02em", color: "var(--paper)" }}><CU to={s.to} /></span>
                  {s.suffix ? <span style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(30px,4vw,60px)", lineHeight: .9, color: "var(--lime-500)" }}>{s.suffix}</span> : null}
                </div>
                <span style={{ display: "block", fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".04em", color: "var(--text-secondary)", marginTop: 16, maxWidth: "20ch", lineHeight: 1.5 }}>{s.label}</span>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* THE SHIFT — explore many, choose one (light) */}
      <section data-theme="light" style={{ background: "var(--bg-base)", borderBottom: "1px solid var(--border-subtle)" }}>
        <div style={{ maxWidth: "var(--maxw-content)", margin: "0 auto", padding: "var(--section-y) var(--page-margin)" }}>
          <Eyebrow>The shift</Eyebrow>
          <div style={{ display: "grid", gridTemplateColumns: "0.9fr 1.1fr", gap: "clamp(32px,5vw,80px)", alignItems: "center", marginTop: "clamp(28px,3vw,44px)" }}>
            <div>
              <h2 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(30px,3.8vw,52px)", lineHeight: 1.08, letterSpacing: "-0.015em", margin: 0, maxWidth: "15ch" }}>Explore many strong routes. Then lock the right one.</h2>
              <p style={{ color: "var(--text-secondary)", fontSize: 17, lineHeight: 1.62, margin: "24px 0 0", maxWidth: "42ch" }}>We use AI to explore multiple powerful visual directions in a fraction of the time. But speed isn't the point — <span style={{ color: "var(--text-primary)" }}>reaching the result you actually pictured is.</span> AI accelerates the search; human judgement chooses and crafts the answer.</p>
            </div>
            <SprintDirections />
          </div>
        </div>
      </section>

      {/* THE METHOD — interactive */}
      <section style={{ maxWidth: "var(--maxw-content)", margin: "0 auto", padding: "var(--section-y) var(--page-margin)" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", flexWrap: "wrap", gap: 16 }}>
          <Eyebrow>The method</Eyebrow>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--text-muted)" }}>05 phases</span>
        </div>
        <div style={{ marginTop: 36 }}>
          <SprintMethod phases={phases} />
        </div>
      </section>

      {/* STATS + CTA */}
      <section style={{ borderTop: "1px solid var(--border-subtle)" }}>
        <div style={{ maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "var(--section-y) var(--page-margin)" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 24, flexWrap: "wrap" }}>
            <Button size="lg" onClick={() => window.DH_NAV("contact")} trailingIcon={<window.ArrowR/>}>Start your sprint</Button>
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".12em", textTransform: "uppercase", color: "var(--text-muted)" }}>Alignment before execution.</span>
          </div>
        </div>
      </section>
    </main>
  );
}

// ——— Premium contact fields (module scope so typing never remounts them) ———
function CField({ label, type = "text", value, onChange, placeholder, required, name, tone = "dark" }) {
  const [foc, setFoc] = React.useState(false);
  const ink = tone === "ink";
  const accent = ink ? "#5f6d22" : "var(--lime-500)";
  const labelCol = foc ? accent : (ink ? "var(--text-muted)" : "rgba(244,244,239,.5)");
  const borderCol = foc ? (ink ? "#9EAD3F" : "var(--lime-500)") : (ink ? "rgba(10,10,11,.18)" : "rgba(244,244,239,.2)");
  const textCol = ink ? "var(--ink-900)" : "#F4F4EF";
  return (
    <label style={{ display: "block" }}>
      <span style={{ display: "block", fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".18em", textTransform: "uppercase", color: labelCol, transition: "color .25s", marginBottom: 12 }}>{label}{required ? <span style={{ color: accent }}> *</span> : null}</span>
      <input name={name} type={type} value={value} onChange={onChange} placeholder={placeholder} required={required}
        onFocus={() => setFoc(true)} onBlur={() => setFoc(false)}
        style={{ width: "100%", boxSizing: "border-box", background: "transparent", border: "none", borderBottom: `1px solid ${borderCol}`, outline: "none", padding: "0 0 14px", color: textCol, fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(20px,1.7vw,26px)", letterSpacing: "-0.01em", transition: "border-color .3s" }} />
    </label>
  );
}
function ChipGroup({ label, options, selected, onPick, multi }) {
  return (
    <div>
      <span style={{ display: "block", fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".18em", textTransform: "uppercase", color: "rgba(244,244,239,.5)", marginBottom: 15 }}>{label}</span>
      <div style={{ display: "flex", flexWrap: "wrap", gap: 10 }}>
        {options.map(o => {
          const on = multi ? selected.includes(o) : selected === o;
          return (
            <button key={o} type="button" onClick={() => onPick(o)} aria-pressed={on}
              style={{ all: "unset", boxSizing: "border-box", cursor: "pointer", fontFamily: "var(--font-sans)", fontWeight: on ? 600 : 500, fontSize: 15, padding: "11px 19px", borderRadius: 999, whiteSpace: "nowrap",
                background: on ? "var(--lime-500)" : "transparent", color: on ? "var(--ink-900)" : "rgba(244,244,239,.82)",
                border: `1px solid ${on ? "var(--lime-500)" : "rgba(244,244,239,.22)"}`, transform: on ? "translateY(-1px)" : "none", transition: "background .25s, color .25s, border-color .25s, transform .2s" }}
              onMouseEnter={(e) => { if (!on) { e.currentTarget.style.borderColor = "var(--lime-500)"; e.currentTarget.style.color = "#F4F4EF"; } }}
              onMouseLeave={(e) => { if (!on) { e.currentTarget.style.borderColor = "rgba(244,244,239,.22)"; e.currentTarget.style.color = "rgba(244,244,239,.82)"; } }}>
              {o}
            </button>
          );
        })}
      </div>
    </div>
  );
}
function ContactRow({ k, v, href }) {
  const inner = <React.Fragment>
    <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".14em", textTransform: "uppercase", color: "rgba(244,244,239,.5)", width: 120, flex: "none" }}>{k}</span>
    <span style={{ fontFamily: "var(--font-sans)", fontSize: 15.5, color: "#F4F4EF" }}>{v}</span>
  </React.Fragment>;
  const base = { display: "flex", alignItems: "center", gap: 18, padding: "14px 0", borderTop: "1px solid rgba(244,244,239,.12)", textDecoration: "none" };
  return href
    ? <a href={href} className="dh-flink" style={base}>{inner}</a>
    : <div style={base}>{inner}</div>;
}

// Start a project — a boutique, self-writing brief taken full-page.
// You pick; the brief drafts itself, live, on a premium sheet.
function ContactView() {
  const NEED = ["a pitch deck", "a campaign", "an event", "a brand system", "templates"];
  const MOMENT = ["raising a round", "launching a product", "a keynote", "a rebrand", "an internal moment"];
  const TIMELINE = ["this month", "this quarter", "still exploring"];
  const [need, setNeed] = React.useState([]);
  const [moment, setMoment] = React.useState(null);
  const [timeline, setTimeline] = React.useState(null);
  const [name, setName] = React.useState("");
  const [email, setEmail] = React.useState("");
  const [status, setStatus] = React.useState("idle"); // idle | sending | sent | error
  const [manual, setManual] = React.useState(false); // freeform "write it yourself" mode
  const [manualBrief, setManualBrief] = React.useState("");
  const ease = "cubic-bezier(.16,1,.3,1)";
  const DEST = "deckhaus@pm.me";
  const emailOk = (v) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v);
  const joinList = (a) => a.length <= 1 ? (a[0] || "") : a.length === 2 ? (a[0] + " and " + a[1]) : (a.slice(0, -1).join(", ") + " and " + a[a.length - 1]);

  const s1 = need.length > 0, s2 = !!moment, s3 = !!timeline;
  const step = s3 ? 3 : (s2 || s1) ? 2 : 1;
  const ready = manual
    ? (manualBrief.trim().length > 0 && name.trim() && emailOk(email.trim()))
    : (s3 && name.trim() && emailOk(email.trim()));

  let brief = "Pick what fits — your brief writes itself.";
  if (need.length && moment) brief = "We're " + moment + " and we need " + joinList(need) + ".";
  else if (moment) brief = "We're preparing " + moment + ".";
  else if (need.length) brief = "We need " + joinList(need) + ".";
  if ((need.length || moment) && timeline) brief += " We'd like to start " + (timeline === "still exploring" ? "soon" : timeline) + ".";
  const briefLive = brief !== "Pick what fits — your brief writes itself.";

  const toggleNeed = (v) => setNeed(p => p.includes(v) ? p.filter(x => x !== v) : [...p, v]);
  const submit = () => {
    if (!ready || status === "sending" || status === "sent") return;
    setStatus("sending");
    fetch("https://formsubmit.co/ajax/" + DEST, {
      method: "POST", headers: { "Content-Type": "application/json", "Accept": "application/json" },
      body: JSON.stringify({ _subject: "New project brief · Deckhaus", _template: "table", _captcha: "false", Name: name.trim(), Email: email.trim(), "What they need": need.join(", "), "The moment": moment || "", Timeline: timeline || "", Brief: manual ? (manualBrief.trim() || brief) : brief }),
    }).then(r => { if (!r.ok) throw new Error("http " + r.status); return r.json().catch(() => ({})); })
      .then(() => setStatus("sent")).catch(() => setStatus("error"));
  };
  const stamp = status === "sent";

  return (
    <main data-theme="dark" style={{ position: "relative", background: "var(--bg-base)", overflow: "hidden" }}>
      {/* ambient: drifting grid + lime glow */}
      <div aria-hidden="true" className="dh-ftgrid" style={{ position: "absolute", inset: 0, pointerEvents: "none", backgroundImage: "linear-gradient(rgba(244,244,239,.05) 1px, transparent 1px), linear-gradient(90deg, rgba(244,244,239,.05) 1px, transparent 1px)", backgroundSize: "60px 60px", WebkitMaskImage: "radial-gradient(120% 80% at 22% 8%, #000 12%, transparent 68%)", maskImage: "radial-gradient(120% 80% at 22% 8%, #000 12%, transparent 68%)" }} />
      <div aria-hidden="true" style={{ position: "absolute", right: "-10%", top: "-16%", width: "60vw", height: "60vw", borderRadius: "50%", background: "radial-gradient(circle, color-mix(in srgb, var(--lime-500) 24%, transparent), transparent 62%)", filter: "blur(130px)", pointerEvents: "none", opacity: .8 }} />

      {/* header band */}
      <section style={{ position: "relative", maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "clamp(46px,6vw,88px) var(--page-margin) clamp(20px,2.4vw,34px)" }}>
        <div className="dh-rise" style={{ display: "inline-flex", alignItems: "center", gap: 10 }}>
          <span style={{ position: "relative", width: 9, height: 9, borderRadius: "50%", background: "var(--lime-500)", animation: "dh-pulse 2.4s ease-out infinite" }} />
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".2em", textTransform: "uppercase", color: "var(--lime-500)" }}>Booking · 2 sprint slots · Q3 2026</span>
        </div>
        <h1 className="dh-rise" style={{ animationDelay: ".07s", fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(44px,6.8vw,112px)", lineHeight: .96, letterSpacing: "-0.02em", margin: "clamp(22px,2.4vw,34px) 0 0", color: "#F4F4EF", maxWidth: "15ch", textWrap: "balance" }}>Tell us the moment. <span style={{ color: "var(--lime-500)" }}>We'll write the brief.</span></h1>
        <p className="dh-rise" style={{ animationDelay: ".14s", fontFamily: "var(--font-sans)", fontSize: "clamp(17px,1.3vw,20px)", lineHeight: 1.62, color: "rgba(244,244,239,.72)", maxWidth: "52ch", margin: "clamp(24px,2.4vw,32px) 0 0" }}>No forms to labour over. Choose what fits and the brief drafts itself — then a senior lead reads it personally and replies within two working days.</p>
      </section>

      {/* the studio — two columns: pick (left) · the brief drafting itself (right) */}
      <section className="dh-rise" style={{ animationDelay: ".2s", position: "relative", maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "clamp(16px,2vw,28px) var(--page-margin) clamp(40px,5vw,72px)", display: "grid", gridTemplateColumns: manual ? "minmax(0, 880px)" : "0.96fr 1.04fr", gap: "clamp(28px,3.4vw,64px)", alignItems: "start", justifyContent: "center" }}>
        {/* LEFT — the picker (guided) */}
        {!manual ? (
        <div style={{ position: "relative", borderRadius: "var(--radius-xl)", border: "1px solid rgba(244,244,239,.14)", background: "linear-gradient(160deg, rgba(22,22,26,.6), rgba(12,12,15,.6))", backdropFilter: "blur(30px)", WebkitBackdropFilter: "blur(30px)", padding: "clamp(28px,3vw,44px)" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", gap: 16, marginBottom: "clamp(24px,2.6vw,34px)" }}>
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".2em", textTransform: "uppercase", color: "var(--lime-500)" }}>Start a brief</span>
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".14em", color: "rgba(244,244,239,.5)" }}>Step 0{step} / 03</span>
          </div>
          {/* progress */}
          <div style={{ display: "flex", gap: 6, marginBottom: "clamp(28px,3vw,40px)" }}>
            {[1, 2, 3].map(n => <span key={n} style={{ flex: 1, height: 3, borderRadius: 2, background: step >= n ? "var(--lime-500)" : "rgba(244,244,239,.14)", transition: `background .4s ${ease}` }} />)}
          </div>

          <div style={{ display: "flex", flexDirection: "column", gap: "clamp(24px,2.6vw,32px)" }}>
            <ChipGroup label="What you need" options={NEED} selected={need} onPick={toggleNeed} multi />
            {s1 ? <div style={{ animation: `dh-fade-up .5s ${ease}` }}><ChipGroup label="The moment" options={MOMENT} selected={moment} onPick={(o) => setMoment(p => p === o ? null : o)} /></div> : null}
            {s2 ? <div style={{ animation: `dh-fade-up .5s ${ease}` }}><ChipGroup label="Timeline" options={TIMELINE} selected={timeline} onPick={(o) => setTimeline(p => p === o ? null : o)} /></div> : null}
            {s3 ? (
              <div style={{ animation: `dh-fade-up .5s ${ease}`, display: "flex", flexDirection: "column", gap: "clamp(22px,2.4vw,30px)", paddingTop: "clamp(6px,1vw,12px)", borderTop: "1px solid rgba(244,244,239,.1)" }}>
                <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "clamp(20px,2.4vw,32px)" }}>
                  <CField label="Name" value={name} onChange={(e) => setName(e.target.value)} placeholder="Your name" required />
                  <CField label="Email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@company.com" required />
                </div>
                <div style={{ display: "flex", alignItems: "center", gap: 18, flexWrap: "wrap" }}>
                  <button type="button" onClick={submit} disabled={!ready || status === "sending" || stamp}
                    style={{ all: "unset", cursor: ready && status === "idle" ? "pointer" : "default", fontFamily: "var(--font-sans)", fontWeight: 600, fontSize: 15.5, padding: "14px 28px", borderRadius: 999, background: stamp ? "transparent" : "var(--lime-500)", color: stamp ? "var(--lime-500)" : "var(--ink-900)", border: `1px solid ${stamp ? "rgba(183,201,74,.55)" : "var(--lime-500)"}`, opacity: (ready || status !== "idle") ? 1 : .45, transition: "all .25s" }}>
                    {status === "sending" ? "Sending…" : stamp ? "Brief sent ✓" : "Send my brief →"}
                  </button>
                  <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".02em", lineHeight: 1.5, color: stamp ? "var(--lime-500)" : status === "error" ? "#D98B5F" : "rgba(244,244,239,.55)", maxWidth: "26ch" }}>
                    {stamp ? `Thanks, ${name.trim().split(" ")[0]} — we'll reply shortly.` : status === "error" ? `Couldn't send — email ${DEST}.` : ready ? "Ready — tap send." : "Add name & email to send."}
                  </span>
                </div>
              </div>
            ) : null}
          </div>
          {/* switch to freeform */}
          <button type="button" onClick={() => setManual(true)}
            style={{ all: "unset", cursor: "pointer", marginTop: "clamp(26px,2.8vw,36px)", display: "inline-flex", alignItems: "center", gap: 8, fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".06em", color: "rgba(244,244,239,.55)", borderBottom: "1px solid rgba(244,244,239,.18)", paddingBottom: 3, transition: "color .2s, border-color .2s" }}
            onMouseEnter={(e) => { e.currentTarget.style.color = "var(--lime-500)"; e.currentTarget.style.borderColor = "var(--lime-500)"; }}
            onMouseLeave={(e) => { e.currentTarget.style.color = "rgba(244,244,239,.55)"; e.currentTarget.style.borderColor = "rgba(244,244,239,.18)"; }}>
            Prefer to write it yourself? →
          </button>
        </div>
        ) : null}

        {/* RIGHT — the brief writing itself */}
        <div style={{ position: "relative" }}>
          <div style={{ position: "relative", background: "var(--paper)", borderRadius: "var(--radius-lg)", boxShadow: "0 50px 100px -46px rgba(0,0,0,.7)", padding: "clamp(28px,3vw,48px)", display: "flex", flexDirection: "column", minHeight: 460, overflow: "hidden" }}>
            <div aria-hidden="true" style={{ position: "absolute", inset: 0, backgroundImage: "linear-gradient(rgba(10,10,11,.04) 1px,transparent 1px)", backgroundSize: "100% 34px", backgroundPosition: "0 92px", pointerEvents: "none", opacity: .5 }} />
            {/* letterhead */}
            <div style={{ position: "relative", display: "flex", justifyContent: "space-between", alignItems: "center", paddingBottom: 20, borderBottom: "1px solid var(--border-default)" }}>
              <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                <img src="assets/logos/deckhaus-mark-black.svg" style={{ height: 24 }} alt="Deckhaus" />
                <span style={{ fontFamily: "var(--font-display)", fontSize: 21, color: "var(--ink-900)" }}>deckhaus</span>
              </div>
              <span style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: ".18em", textTransform: "uppercase", color: "var(--text-muted)" }}>Project brief</span>
            </div>
            {!manual ? (<React.Fragment>
            {/* client + date row */}
            <div style={{ position: "relative", display: "grid", gridTemplateColumns: "1fr 1fr", gap: 18, padding: "22px 0", borderBottom: "1px solid var(--border-default)" }}>
              <div><div style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--text-muted)" }}>Prepared for</div><div style={{ fontFamily: "var(--font-display)", fontSize: 18, color: name.trim() ? "var(--ink-900)" : "var(--text-muted)", marginTop: 6, transition: "color .3s" }}>{name.trim() || "—"}</div></div>
              <div><div style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--text-muted)" }}>Reference</div><div style={{ fontFamily: "var(--font-mono)", fontSize: 14, color: "var(--ink-900)", marginTop: 8 }}>DH-2026-{String((need.length * 7 + (moment ? MOMENT.indexOf(moment) + 1 : 0) * 3 + (timeline ? TIMELINE.indexOf(timeline) + 1 : 0))).padStart(3, "0")}</div></div>
            </div>
            {/* summary lines */}
            <div style={{ position: "relative", display: "flex", flexDirection: "column", gap: 13, padding: "22px 0" }}>
              {[["Need", need.length ? joinList(need) : "—"], ["Moment", moment || "—"], ["Timeline", timeline ? (timeline === "still exploring" ? "exploring" : timeline) : "—"]].map(([k, v]) => (
                <div key={k} style={{ display: "grid", gridTemplateColumns: "92px 1fr", gap: 14, alignItems: "baseline" }}>
                  <span style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--text-muted)" }}>{k}</span>
                  <span style={{ fontFamily: "var(--font-sans)", fontSize: 15.5, color: v === "—" ? "var(--text-muted)" : "var(--ink-900)", transition: "color .3s" }}>{v}</span>
                </div>
              ))}
            </div>
            {/* the living statement */}
            <p style={{ position: "relative", fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(23px,2.3vw,34px)", lineHeight: 1.28, letterSpacing: "-0.01em", color: briefLive ? "var(--ink-900)" : "var(--text-muted)", margin: "8px 0 0", textWrap: "pretty" }}>
              {brief}<span aria-hidden="true" style={{ display: "inline-block", width: 2, height: "1em", marginLeft: 3, background: "#9EAD3F", verticalAlign: "-0.12em", animation: "dh-caret 1s steps(1) infinite" }} />
            </p>
            {/* signature / status footer */}
            <div style={{ position: "relative", marginTop: "auto", paddingTop: 26, display: "flex", justifyContent: "space-between", alignItems: "flex-end", gap: 16 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                <span style={{ width: 26, height: 2, background: s3 ? "#9EAD3F" : "var(--border-default)", flex: "none", transition: "background .3s" }} />
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".1em", textTransform: "uppercase", color: "var(--text-muted)" }}>{stamp ? "Submitted" : s3 ? "Ready to send" : "Drafting…"}</span>
              </div>
              <span style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: ".08em", color: "var(--text-disabled)" }}>Deckhaus Studio · 2026</span>
            </div>
            </React.Fragment>) : (<React.Fragment>
            {/* freeform brief body */}
            <div style={{ position: "relative", padding: "22px 0 0", flex: 1, display: "flex", flexDirection: "column" }}>
              <span style={{ display: "block", fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--text-muted)", marginBottom: 16 }}>In your words</span>
              <textarea value={manualBrief} onChange={(e) => setManualBrief(e.target.value)} placeholder="Tell us the moment, what you need, and roughly when. A few honest lines beat a long spec — we'll shape the rest together."
                style={{ width: "100%", boxSizing: "border-box", flex: 1, minHeight: 210, resize: "vertical", background: "transparent", border: "none", outline: "none", fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(21px,2.1vw,31px)", lineHeight: 1.3, letterSpacing: "-0.01em", color: "var(--ink-900)" }} />
            </div>
            {/* fields + actions */}
            <div style={{ position: "relative", marginTop: 4, paddingTop: 26, borderTop: "1px solid var(--border-default)", display: "flex", flexDirection: "column", gap: "clamp(20px,2.2vw,26px)" }}>
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "clamp(22px,2.6vw,40px)" }}>
                <CField tone="ink" label="Name" value={name} onChange={(e) => setName(e.target.value)} placeholder="Your name" required />
                <CField tone="ink" label="Email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@company.com" required />
              </div>
              <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16, flexWrap: "wrap" }}>
                <div style={{ display: "flex", alignItems: "center", gap: 16, flexWrap: "wrap" }}>
                  <button type="button" onClick={submit} disabled={!ready || status === "sending" || stamp}
                    style={{ all: "unset", cursor: ready && status === "idle" ? "pointer" : "default", fontFamily: "var(--font-sans)", fontWeight: 600, fontSize: 15.5, padding: "14px 28px", borderRadius: 999, background: stamp ? "transparent" : "var(--ink-900)", color: stamp ? "#5f6d22" : "var(--paper)", border: `1px solid ${stamp ? "rgba(95,109,34,.5)" : "var(--ink-900)"}`, opacity: (ready || status !== "idle") ? 1 : .4, transition: "all .25s" }}>
                    {status === "sending" ? "Sending…" : stamp ? "Brief sent ✓" : "Send my brief →"}
                  </button>
                  <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".02em", color: stamp ? "#5f6d22" : status === "error" ? "#B4622F" : "var(--text-muted)", maxWidth: "24ch", lineHeight: 1.5 }}>
                    {stamp ? `Thanks, ${name.trim().split(" ")[0]} — we'll reply shortly.` : status === "error" ? `Couldn't send — email ${DEST}.` : ready ? "Ready — tap send." : "Write a line, add name & email."}
                  </span>
                </div>
                <button type="button" onClick={() => setManual(false)}
                  style={{ all: "unset", cursor: "pointer", fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".06em", textTransform: "uppercase", color: "var(--text-muted)", borderBottom: "1px solid transparent", paddingBottom: 2, transition: "color .2s, border-color .2s" }}
                  onMouseEnter={(e) => { e.currentTarget.style.color = "var(--ink-900)"; e.currentTarget.style.borderColor = "rgba(10,10,11,.3)"; }}
                  onMouseLeave={(e) => { e.currentTarget.style.color = "var(--text-muted)"; e.currentTarget.style.borderColor = "transparent"; }}>
                  ← Guided
                </button>
              </div>
            </div>
            </React.Fragment>)}
            {/* submitted stamp */}
            {stamp ? (
              <div aria-hidden="true" style={{ position: "absolute", right: "clamp(20px,3vw,44px)", top: "clamp(96px,12vw,150px)", transform: "rotate(-11deg)", border: "2.5px solid #7a8b2e", color: "#7a8b2e", borderRadius: 8, padding: "8px 16px", fontFamily: "var(--font-mono)", fontSize: 15, letterSpacing: ".16em", textTransform: "uppercase", opacity: .82, animation: `dh-demo-pop .5s ${ease}` }}>Received</div>
            ) : null}
          </div>
        </div>
      </section>

      {/* quiet detail strip — no pricing, just the essentials */}
      <section style={{ position: "relative", maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "0 var(--page-margin) clamp(56px,7vw,104px)" }}>
        <div className="dh-mstack" style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: "clamp(20px,3vw,48px)" }}>
          {[["Email", "hola@deckhaus.studio", "mailto:hola@deckhaus.studio"], ["Response", "Yesterday ;)", null], ["Studio", "Built across borders · remote", null]].map(([k, v, href]) => (
            <ContactRow key={k} k={k} v={v} href={href} />
          ))}
        </div>
      </section>
    </main>
  );
}

Object.assign(window, { CaseCard, WorkView, ServicesView, SprintView, ContactView, CaseStudyView });

function CU({ to, dur = 2200, suffix = "" }) {
  const ref = React.useRef(null);
  const [v, setV] = React.useState(0);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) { setV(to); return; }
    let raf = null, started = false;
    const io = new IntersectionObserver((es) => es.forEach(e => {
      if (e.isIntersecting && !started) { started = true; const t0 = performance.now();
        const step = (t) => { const p = Math.min(1, (t - t0) / dur); setV(Math.round((1 - Math.pow(1 - p, 4)) * to)); if (p < 1) raf = requestAnimationFrame(step); };
        raf = requestAnimationFrame(step); io.disconnect(); }
    }), { threshold: 0.6 });
    io.observe(el); return () => { io.disconnect(); if (raf) cancelAnimationFrame(raf); };
  }, [to, dur]);
  return <span ref={ref}>{v}{suffix}</span>;
}

function TJVisual({ kind, shown, slides, palette }) {
  const box = { position: "relative", height: "clamp(120px,12vw,158px)", marginBottom: "clamp(20px,2.2vw,30px)", overflow: "hidden" };
  const card = (extra) => Object.assign({ position: "absolute", borderRadius: 5, background: "#fff", border: "1px solid rgba(10,10,11,.12)", boxShadow: "0 10px 22px -14px rgba(0,0,0,.3)" }, extra);
  const bar = (c, w) => ({ position: "absolute", left: 8, height: 3, borderRadius: 2, background: c, width: w });
  if (kind === 0) {
    // Before — fragmented, misaligned
    const items = [
      { left: "2%", top: "14%", width: "46%", height: "40%", rot: -8 },
      { left: "52%", top: "4%", width: "44%", height: "36%", rot: 6 },
      { left: "10%", top: "56%", width: "42%", height: "38%", rot: 5 },
      { left: "56%", top: "50%", width: "40%", height: "42%", rot: -6 },
    ];
    return (
      <div style={box}>
        {items.map((it, k) => (
          <div key={k} style={card({ left: it.left, top: it.top, width: it.width, height: it.height, transform: `rotate(${shown ? it.rot : 0}deg)`, opacity: shown ? 1 : 0, filter: "grayscale(1)", transition: `transform .7s cubic-bezier(.16,1,.3,1) ${k * 0.09}s, opacity .5s ease ${k * 0.09}s` })}>
            <span style={{ ...bar("rgba(10,10,11,.5)", "64%"), top: 9 }} />
            <span style={{ ...bar("rgba(10,10,11,.18)", "44%"), top: 18 }} />
          </div>
        ))}
      </div>
    );
  }
  if (kind === 1) {
    // The system — snapping into a tidy grid
    return (
      <div style={box}>
        <div style={{ position: "absolute", inset: "6% 2%", display: "grid", gridTemplateColumns: "repeat(3,1fr)", gridTemplateRows: "repeat(2,1fr)", gap: 8 }}>
          {[0, 1, 2, 3, 4, 5].map((k) => (
            <div key={k} style={{ position: "relative", borderRadius: 4, background: "#fff", border: "1px solid rgba(10,10,11,.12)", boxShadow: "0 8px 18px -12px rgba(0,0,0,.28)", overflow: "hidden", opacity: shown ? 1 : 0, transform: shown ? "scale(1)" : "scale(.7)", transition: `all .55s cubic-bezier(.16,1,.3,1) ${k * 0.07}s` }}>
              <span style={{ position: "absolute", left: 0, top: 0, bottom: 0, width: 3, background: palette && palette.length ? palette[k % palette.length][0] : "var(--lime-500)" }} />
            </div>
          ))}
        </div>
      </div>
    );
  }
  // After — the real deck, on-brand thumbnails
  if (slides && slides.length) {
    return (
      <div style={box}>
        <div style={{ position: "absolute", inset: "2% 0", display: "grid", gridTemplateColumns: "repeat(3,1fr)", gridAutoRows: "1fr", gap: 7 }}>
          {slides.slice(0, 6).map(([img], k) => (
            <div key={k} style={{ position: "relative", borderRadius: 4, overflow: "hidden", border: "1px solid rgba(10,10,11,.1)", boxShadow: "0 8px 18px -12px rgba(0,0,0,.3)", opacity: shown ? 1 : 0, transform: shown ? "scale(1)" : "scale(.72)", transition: `all .55s cubic-bezier(.16,1,.3,1) ${k * 0.07}s` }}>
              <img src={"assets/work/" + img} alt="" loading="lazy" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }} />
            </div>
          ))}
        </div>
      </div>
    );
  }
  // After — one unified, on-brand card (fallback)
  if (palette && palette.length) {
    return (
      <div style={box}>
        <div style={{ position: "absolute", inset: "6% 6%", borderRadius: 7, background: "#fff", border: "1px solid rgba(10,10,11,.12)", boxShadow: "0 22px 44px -22px rgba(0,0,0,.35)", overflow: "hidden", display: "flex", flexDirection: "column", opacity: shown ? 1 : 0, transform: shown ? "translateY(0)" : "translateY(14px)", transition: "all .7s cubic-bezier(.16,1,.3,1) .15s" }}>
          <div style={{ display: "flex", height: "54%" }}>
            {palette.slice(0, 6).map(([hex], k) => (
              <div key={k} style={{ flex: 1, background: hex, transform: shown ? "scaleY(1)" : "scaleY(0)", transformOrigin: "top", transition: `transform .55s cubic-bezier(.16,1,.3,1) ${0.25 + k * 0.07}s` }} />
            ))}
          </div>
          <div style={{ flex: 1, padding: "11px 13px", display: "flex", flexDirection: "column", justifyContent: "center" }}>
            <span style={{ display: "block", height: 6, width: "58%", borderRadius: 3, background: "var(--ink-900)" }} />
            <span style={{ display: "block", height: 4, width: "40%", borderRadius: 2, background: "rgba(10,10,11,.25)", marginTop: 8 }} />
          </div>
        </div>
      </div>
    );
  }
  return (
    <div style={box}>
      <div style={{ position: "absolute", inset: "8% 14%", borderRadius: 7, background: "#fff", border: "1px solid rgba(10,10,11,.12)", boxShadow: "0 22px 44px -22px rgba(0,0,0,.35)", overflow: "hidden", opacity: shown ? 1 : 0, transform: shown ? "translateY(0)" : "translateY(14px)", transition: "all .7s cubic-bezier(.16,1,.3,1) .15s" }}>
        <span style={{ position: "absolute", left: 0, top: 0, bottom: 0, width: 6, background: "var(--lime-500)" }} />
        <span style={{ position: "absolute", left: 20, top: 22, height: 6, width: "52%", borderRadius: 3, background: "var(--ink-900)" }} />
        <span style={{ position: "absolute", left: 20, top: 36, height: 4, width: "38%", borderRadius: 2, background: "rgba(10,10,11,.25)" }} />
        <span style={{ position: "absolute", left: 20, bottom: 20, height: 12, width: 12, borderRadius: "50%", border: "2px solid var(--lime-500)" }} />
      </div>
    </div>
  );
}

function TransformationJourney({ items, slides, palette }) {
  const ref = React.useRef(null);
  const [shown, setShown] = React.useState(false);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) { setShown(true); return; }
    const io = new IntersectionObserver((es) => es.forEach(e => { if (e.isIntersecting) { setShown(true); io.disconnect(); } }), { threshold: 0.3 });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  const n = items.length;
  return (
    <div ref={ref} style={{ marginTop: "clamp(40px,4.5vw,64px)" }}>
      {/* connecting rail */}
      <div style={{ position: "relative", height: 2, background: "var(--border-default)", marginBottom: "clamp(30px,3.4vw,46px)" }}>
        <div style={{ position: "absolute", inset: 0, transformOrigin: "left", transform: shown ? "scaleX(1)" : "scaleX(0)", background: "var(--lime-500)", transition: "transform 1.2s cubic-bezier(.16,1,.3,1) .15s" }} />
        {items.map((_, i) => (
          <span key={i} aria-hidden="true" style={{ position: "absolute", top: "50%", left: `${(i / (n - 1)) * 100}%`, transform: "translate(-50%,-50%)", width: i === n - 1 ? 15 : 12, height: i === n - 1 ? 15 : 12, borderRadius: "50%", background: shown ? (i === n - 1 ? "var(--lime-500)" : "var(--ink-900)") : "var(--border-default)", boxShadow: "0 0 0 5px var(--bg-base)", transition: `background .5s ease ${0.25 + i * 0.28}s, transform .5s cubic-bezier(.16,1,.3,1) ${0.25 + i * 0.28}s` }} />
        ))}
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 0 }}>
        {items.map(([t, x], i) => {
          const last = i === n - 1;
          return (
            <div key={t} style={{ position: "relative", padding: "0 clamp(18px,2vw,34px)", borderLeft: i > 0 ? "1px solid var(--border-default)" : "none", display: "flex", flexDirection: "column", opacity: shown ? 1 : 0, transform: shown ? "none" : "translateY(18px)", transition: `opacity .7s ease ${0.2 + i * 0.18}s, transform .7s cubic-bezier(.16,1,.3,1) ${0.2 + i * 0.18}s` }}>
              <TJVisual kind={i} shown={shown} slides={last ? slides : null} palette={palette} />
              <div style={{ display: "flex", alignItems: "baseline", gap: 14 }}>
                <span style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(44px,5vw,78px)", lineHeight: .82, letterSpacing: "-0.02em", color: last ? "var(--text-accent)" : "transparent", WebkitTextStroke: last ? "0" : "1.4px rgba(10,10,11,.22)" }}>{String(i + 1).padStart(2, "0")}</span>
                {!last ? <span aria-hidden="true" style={{ color: "var(--text-muted)", fontFamily: "var(--font-display)", fontSize: 26 }}>→</span> : null}
              </div>
              <h3 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(22px,2.2vw,31px)", lineHeight: 1.08, letterSpacing: "-0.01em", margin: "clamp(22px,2.4vw,32px) 0 0", color: last ? "var(--text-accent)" : "var(--text-primary)" }}>{t}</h3>
              <span style={{ display: "block", width: 34, height: 2, background: last ? "var(--lime-500)" : "rgba(10,10,11,.18)", margin: "18px 0 0" }} />
              <p style={{ fontFamily: "var(--font-sans)", fontSize: "clamp(15px,1.15vw,17px)", lineHeight: 1.62, color: "var(--text-secondary)", margin: "18px 0 0" }}>{x}</p>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function DeckStack({ slides, bg, fig }) {
  const n = slides.length;
  const [active, setActive] = React.useState(0);
  const [paused, setPaused] = React.useState(false);
  React.useEffect(() => {
    if (paused) return;
    const reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (reduce) return;
    const t = setInterval(() => setActive(a => (a + 1) % n), 1500);
    return () => clearInterval(t);
  }, [paused, n]);
  return (
    <div onMouseEnter={() => setPaused(true)} onMouseLeave={() => setPaused(false)}
      style={{ position: "relative", aspectRatio: "16 / 8.6", perspective: "1800px" }}>
      <div aria-hidden="true" style={{ position: "absolute", inset: "-6% -4%", background: "radial-gradient(48% 48% at 52% 42%, color-mix(in srgb, var(--lime-500) 12%, transparent), transparent 72%)", filter: "blur(30px)", pointerEvents: "none" }} />
      <div style={{ position: "absolute", top: 0, left: 0, right: 0, bottom: "clamp(52px,6vw,74px)", display: "flex", alignItems: "center", justifyContent: "center" }}>
        {slides.map(([img, label], i) => {
          const slot = (i - active + n) % n;
          const vis = slot < 4;
          return (
            <div key={img} style={{ position: "absolute", width: "90%", aspectRatio: "16 / 9", borderRadius: 14, overflow: "hidden", border: "1px solid rgba(255,255,255,.16)", boxShadow: "0 60px 120px -34px rgba(0,0,0,.42)", transform: `translate(${slot * 2.6}%, ${slot * 4}%) scale(${1 - slot * 0.06}) rotate(${slot * 0.6}deg)`, opacity: vis ? (1 - slot * 0.16) : 0, zIndex: n - slot, transition: "transform .55s cubic-bezier(.16,1,.3,1), opacity .4s ease" }}>
              <img src={"assets/work/" + img} alt={label} draggable="false" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }} />
            </div>
          );
        })}
      </div>
      <div style={{ position: "absolute", left: "50%", bottom: 0, transform: "translateX(-50%)", zIndex: 30, display: "inline-flex", alignItems: "center", gap: 16, padding: "11px 18px", borderRadius: 999, background: "rgba(255,255,255,.72)", backdropFilter: "blur(14px)", WebkitBackdropFilter: "blur(14px)", border: "1px solid rgba(10,10,11,.08)", boxShadow: "0 18px 40px -22px rgba(0,0,0,.3)" }}>
        <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".04em", textTransform: "uppercase", color: "var(--ink-900)", whiteSpace: "nowrap" }}>{String(active + 1).padStart(2, "0")} · {slides[active][1]}</span>
        <div style={{ display: "flex", gap: 7 }}>
          {slides.map(([img], i) => (
            <button key={img} onClick={() => setActive(i)} aria-label={"Slide " + (i + 1)} style={{ all: "unset", cursor: "pointer", width: i === active ? 20 : 7, height: 7, borderRadius: 999, background: i === active ? "var(--lime-500)" : "rgba(10,10,11,.2)", transition: "all .3s cubic-bezier(.16,1,.3,1)" }} />
          ))}
        </div>
      </div>
    </div>
  );
}

function LaptopDeck({ slides }) {
  const wrapRef = React.useRef(null);
  const colRefs = React.useRef([]);
  React.useEffect(() => {
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
    let raf = null;
    const update = () => {
      raf = null;
      const el = wrapRef.current; if (!el) return;
      const r = el.getBoundingClientRect();
      const vh = window.innerHeight || 1;
      const p = Math.max(0, Math.min(1, (vh - r.top) / (vh + r.height)));
      const amp = [-180, 130, -120, 160];
      colRefs.current.forEach((c, i) => { if (c) c.style.transform = "translateY(" + ((p - 0.5) * amp[i % amp.length]) + "px)"; });
    };
    const onScroll = () => { if (raf == null) raf = requestAnimationFrame(update); };
    update();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    return () => { window.removeEventListener("scroll", onScroll); window.removeEventListener("resize", onScroll); if (raf) cancelAnimationFrame(raf); };
  }, []);
  const pool = slides.concat(slides, slides, slides);
  const cols = [0, 1, 2, 3, 4, 5];
  return (
    <div ref={wrapRef} style={{ position: "relative", width: "100vw", marginLeft: "calc(50% - 50vw)", height: "min(86vh, 880px)", overflow: "hidden", background: "#eef0f2" }}>
      <div aria-hidden="true" style={{ position: "absolute", inset: "-14%", pointerEvents: "none", backgroundImage: "url(assets/work/lazura/soft-bg.png)", backgroundSize: "cover", backgroundPosition: "center", filter: "blur(60px) saturate(1.08)", opacity: .7, transform: "scale(1.15)" }} />
      <div aria-hidden="true" style={{ position: "absolute", inset: 0, background: "rgba(245,246,244,.4)", pointerEvents: "none" }} />
      <div style={{ position: "absolute", inset: "-28%", display: "flex", gap: "clamp(10px,1vw,16px)", transform: "rotate(-8deg) scale(1.14)", transformOrigin: "center" }}>
        {cols.map((ci) => (
          <div key={ci} ref={(el) => (colRefs.current[ci] = el)} style={{ flex: 1, display: "flex", flexDirection: "column", gap: "clamp(10px,1vw,16px)", willChange: "transform", marginTop: ci % 2 ? "clamp(-70px,-6vw,-30px)" : "0" }}>
            {pool.map(([img], i) => (i % 6 === ci ? (
              <div key={i} style={{ borderRadius: 10, overflow: "hidden", border: "1px solid rgba(10,10,11,.08)", boxShadow: "0 34px 64px -30px rgba(0,0,0,.32)" }}>
                <img src={"assets/work/" + img} alt="" draggable="false" style={{ display: "block", width: "100%", height: "auto" }} />
              </div>
            ) : null))}
          </div>
        ))}
      </div>
    </div>
  );
}

function ClaudeWorkspace({ prompts, slides }) {
  const [pi, setPi] = React.useState(0);
  const [typed, setTyped] = React.useState("");
  const [built, setBuilt] = React.useState(0);
  React.useEffect(() => {
    const reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const timers = []; let cancelled = false;
    const full = prompts[pi];
    setTyped(""); setBuilt(0);
    if (reduce) { setTyped(full); setBuilt(4); timers.push(setTimeout(() => { if (!cancelled) setPi((pi + 1) % prompts.length); }, 4000)); return () => { cancelled = true; timers.forEach(clearTimeout); }; }
    let ch = 0;
    const type = () => { ch++; setTyped(full.slice(0, ch)); if (ch < full.length) timers.push(setTimeout(type, 26)); else { let b = 0; const build = () => { b++; setBuilt(b); if (b < 4) timers.push(setTimeout(build, 260)); else timers.push(setTimeout(() => { if (!cancelled) setPi((pi + 1) % prompts.length); }, 2400)); }; timers.push(setTimeout(build, 520)); } };
    timers.push(setTimeout(type, 450));
    return () => { cancelled = true; timers.forEach(clearTimeout); };
  }, [pi, prompts]);
  const thumbs = (slides || []).slice(0, 4);
  return (
    <div style={{ background: "rgba(255,255,255,.04)", border: "1px solid rgba(255,255,255,.12)", borderRadius: "var(--radius-lg)", overflow: "hidden", boxShadow: "0 40px 80px -44px rgba(0,0,0,.6)" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 9, padding: "12px 16px", borderBottom: "1px solid rgba(255,255,255,.08)" }}>
        {["#ff5f57", "#febc2e", "#28c840"].map(c => <span key={c} style={{ width: 9, height: 9, borderRadius: "50%", background: c, opacity: .85 }} />)}
        <span style={{ marginLeft: 6, fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".08em", color: "var(--text-muted)" }}>Deckhaus · Lazura workspace</span>
      </div>
      <div style={{ padding: "18px 18px 0" }}>
        <div style={{ display: "flex", gap: 12, alignItems: "flex-start", background: "rgba(255,255,255,.05)", border: "1px solid rgba(255,255,255,.1)", borderRadius: 10, padding: "14px 16px", minHeight: 44 }}>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 13, color: "var(--lime-500)", flex: "none", marginTop: 1 }}>›</span>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 13.5, lineHeight: 1.55, color: "rgba(244,244,239,.9)" }}>{typed}<span aria-hidden="true" style={{ display: "inline-block", width: 7, height: "1.05em", marginLeft: 2, background: "var(--lime-500)", verticalAlign: "-2px", animation: "dh-caret 1s steps(1) infinite" }} /></span>
        </div>
      </div>
      <div style={{ padding: "16px 18px 20px" }}>
        <span style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: ".14em", textTransform: "uppercase", color: built > 0 ? "var(--lime-500)" : "var(--text-muted)", transition: "color .3s" }}>{built >= 4 ? "✓ On-brand draft ready" : built > 0 ? "Assembling on-brand draft…" : "Waiting for prompt…"}</span>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 8, marginTop: 12 }}>
          {thumbs.map(([img], i) => (
            <div key={i} style={{ aspectRatio: "16 / 9", borderRadius: 5, overflow: "hidden", border: "1px solid rgba(255,255,255,.14)", opacity: i < built ? 1 : 0, transform: i < built ? "translateY(0) scale(1)" : "translateY(10px) scale(.9)", transition: "all .5s cubic-bezier(.16,1,.3,1)" }}>
              <img src={"assets/work/" + img} alt="" draggable="false" style={{ width: "100%", height: "100%", objectFit: "cover" }} />
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function MoodParallax({ src, alt }) {
  const wrapRef = React.useRef(null);
  const imgRef = React.useRef(null);
  React.useEffect(() => {
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
    let raf = null;
    const update = () => {
      raf = null;
      const el = wrapRef.current, im = imgRef.current; if (!el || !im) return;
      const r = el.getBoundingClientRect();
      const vh = window.innerHeight || 1;
      const p = Math.max(0, Math.min(1, (vh - r.top) / (vh + r.height)));
      im.style.transform = "scale(1.32) translateY(" + ((p - 0.5) * -24) + "%)";
    };
    const onScroll = () => { if (raf == null) raf = requestAnimationFrame(update); };
    update();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    return () => { window.removeEventListener("scroll", onScroll); window.removeEventListener("resize", onScroll); if (raf) cancelAnimationFrame(raf); };
  }, []);
  return (
    <div ref={wrapRef} style={{ position: "relative", width: "100vw", marginLeft: "calc(50% - 50vw)", overflow: "hidden", background: "#0D47A1" }}>
      <img ref={imgRef} src={src} alt={alt} draggable="false" style={{ display: "block", width: "100%", height: "auto", transform: "scale(1.05)", willChange: "transform" }} />
    </div>
  );
}

function Reveal({ children, delay }) {
  const ref = React.useRef(null);
  const [shown, setShown] = React.useState(false);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) { setShown(true); return; }
    const io = new IntersectionObserver((es) => es.forEach(e => { if (e.isIntersecting) { setShown(true); io.disconnect(); } }), { threshold: 0.18 });
    io.observe(el); return () => io.disconnect();
  }, []);
  return <div ref={ref} style={{ opacity: shown ? 1 : 0, transform: shown ? "none" : "translateY(34px)", transition: `opacity 1s cubic-bezier(.16,1,.3,1) ${delay || 0}s, transform 1s cubic-bezier(.16,1,.3,1) ${delay || 0}s` }}>{children}</div>;
}

function ImmersivePoster({ src, text }) {
  const wrapRef = React.useRef(null);
  const imgRef = React.useRef(null);
  const [typed, setTyped] = React.useState("");
  React.useEffect(() => {
    const reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    let raf = null, io = null;
    const update = () => {
      raf = null;
      const el = wrapRef.current, im = imgRef.current; if (!el || !im) return;
      const r = el.getBoundingClientRect();
      const vh = window.innerHeight || 1;
      const p = Math.max(0, Math.min(1, (vh - r.top) / (vh + r.height)));
      im.style.transform = "translateX(" + ((p - 0.5) * 18 + 20) + "%) scale(1.04)";
    };
    const onScroll = () => { if (raf == null) raf = requestAnimationFrame(update); };
    if (!reduce) { update(); window.addEventListener("scroll", onScroll, { passive: true }); window.addEventListener("resize", onScroll); }
    const tel = wrapRef.current;
    if (tel) {
      io = new IntersectionObserver((es) => es.forEach(e => {
        if (e.isIntersecting) {
          io.disconnect();
          if (reduce) { setTyped(text); return; }
          let ch = 0; const step = () => { ch++; setTyped(text.slice(0, ch)); if (ch < text.length) setTimeout(step, 18); };
          setTimeout(step, 300);
        }
      }), { threshold: 0.4 });
      io.observe(tel);
    }
    return () => { if (raf) cancelAnimationFrame(raf); if (io) io.disconnect(); window.removeEventListener("scroll", onScroll); window.removeEventListener("resize", onScroll); };
  }, [text]);
  return (
    <div ref={wrapRef} style={{ position: "relative", width: "100vw", marginLeft: "calc(50% - 50vw)", height: "min(90vh, 900px)", overflow: "hidden", background: "#0b1220" }}>
      <img ref={imgRef} src={src} alt="" draggable="false" style={{ position: "absolute", top: 0, left: "-8%", width: "116%", height: "100%", objectFit: "cover", willChange: "transform" }} />
      <div aria-hidden="true" style={{ position: "absolute", inset: 0, background: "linear-gradient(90deg, rgba(6,10,18,.92) 0%, rgba(6,10,18,.82) 30%, rgba(6,10,18,.3) 46%, transparent 60%)" }} />
      <div style={{ position: "absolute", inset: 0, display: "flex", alignItems: "center" }}>
        <div style={{ maxWidth: "var(--maxw-wide)", width: "100%", margin: "0 auto", padding: "0 var(--page-margin)" }}>
          <div style={{ maxWidth: "clamp(320px, 40vw, 560px)" }}>
            <span style={{ display: "inline-flex", alignItems: "center", gap: 10, fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".2em", textTransform: "uppercase", color: "var(--lime-500)" }}><span style={{ width: 20, height: 2, background: "var(--lime-500)" }} />Out in Genève</span>
            <p style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(24px,2.8vw,40px)", lineHeight: 1.24, letterSpacing: "-0.01em", margin: "clamp(20px,2vw,28px) 0 0", color: "#F4F4EF", minHeight: "4em" }}>{typed}<span aria-hidden="true" style={{ display: "inline-block", width: 3, height: "1em", marginLeft: 3, background: "var(--lime-500)", verticalAlign: "-0.12em", animation: "dh-caret 1s steps(1) infinite" }} /></p>
          </div>
        </div>
      </div>
    </div>
  );
}

const CASE_DATA = {
  "lazura": {
    badge: "Case study",
    title: "Lazura", titleTail: "— Investor Pitch System",
    intro: "A Swiss fintech raising on trust. The pitch had to feel as calm, precise and human as the product — and the team had to be able to rebuild it, on-brand, without us in the room.",
    meta: [["Client", "Lazura"], ["Sector", "Fintech · Banking"], ["Services", "Pitch deck · Narrative system"], ["Role", "Narrative, design & Claude workspace"], ["Year", "2026"]],
    heroImg: "assets/work/lazura/cover.png", heroScale: 1.02, heroBg: "linear-gradient(135deg, #7a1418, #0b0f14)", heroFig: "Fig. 01 — Lazura · Genève",
    brief: ["A strong story with no system behind it. Every new deck was rebuilt from scratch — so the real problem wasn't one pitch, it was ", "how the team could tell the same story, on-brand, every single time", ", without starting from a blank slide."],
    transformation: [
      ["Before", "A powerful vision trapped in one-off slides — every investor meeting meant rebuilding the deck, re-formatting, re-deciding what the brand even looked like."],
      ["The system", "One reusable narrative, a library of on-brand components and a Claude workspace that assembles new decks from approved building blocks."],
      ["After", "The team ships investor-ready decks in minutes, not weeks — coherent, on-brand, and impossible to knock off-message."],
    ],
    steps: [
      { n: "01", t: "The narrative", d: "We wrote the investor story once — problem, shift, mission, product, ask — as a reusable spine every future deck can follow." },
      { n: "02", t: "Visual system", d: "A calm, Swiss visual language: type scale, grid, gradient system and data treatments — precision that reads as trust." },
      { n: "03", t: "Component library", d: "On-brand slide components — stat, quote, product, mission, contact — built to recombine without ever breaking the brand." },
      { n: "04", t: "Claude workspace", d: "A Claude workspace loaded with the narrative and the components, so the team drafts new, on-brand decks from a prompt — not a blank slide." },
      { n: "05", t: "Handoff", d: "Guidelines and a living template: the team now produces investor-ready material on their own, on-brand every time." },
    ],
    quote: ["Tell the story once. ", "Ship it forever."],
    results: [{ to: 90, suffix: "%", label: "less time rebuilding decks from scratch" }, { to: 1, suffix: "", label: "reusable narrative behind every pitch" }, { to: 5, suffix: "×", label: "faster to an investor-ready deck" }],
    deck: {
      kicker: "The deck",
      note: "One narrative, many slides",
      blurb: "The reusable investor story — from the opening stat to the ask — assembled from on-brand components.",
      slides: [
        ["lazura/cover.png", "Opening · the market shift"],
        ["lazura/trust-shifts.png", "Data · trust shifts"],
        ["lazura/mission.png", "Mission"],
        ["lazura/reimagined.png", "Product · why it matters"],
        ["lazura/growth.png", "Market · the opportunity"],
        ["lazura/app.png", "Product · the app"],
        ["lazura/wellbeing.png", "Belief · the human ROI"],
        ["lazura/contact.png", "The ask · contact"],
      ],
    },
    components: {
      kicker: "The component system",
      blurb: "Every slide is built from the same approved blocks. Recombine them and the deck stays on-brand — no reformatting, no drift.",
      items: [
        ["Stat block", "A headline number, a supporting line, a gradient field — the trust-shift and growth slides are the same component."],
        ["Mission statement", "Big claim left, brand promise right — reused for mission and belief moments."],
        ["Product panel", "Device mock, three proof points, a paragraph of context — drop in any screen."],
        ["Contact / ask", "The close: who, where, how to reach us — identical every deck."],
      ],
    },
    claude: {
      kicker: "The Claude workspace",
      blurb: "We loaded the narrative spine and the component library into a Claude workspace. The team describes the meeting; Claude assembles a first draft from approved blocks — on-brand from the first slide.",
      prompts: [
        "Draft a 6-slide seed round deck for a Series A investor — lead with the trust-shift stat.",
        "Swap the product slide for the cards screen and tighten the ask.",
        "Make a 3-slide teaser from this deck for a cold intro email.",
      ],
    },
    deliverBlurb: "One story, one system, one workspace — so a small team pitches like a big one, every time.",
    deliverables: ["Investor narrative", "Visual system & grid", "Slide component library", "PowerPoint template", "Claude deck workspace", "Usage guidelines"],
    next: { label: "Café Vision — Brand Launch System", slug: "cafe-vision" },
  },
  "lacoste": {
    badge: "Case study",
    title: "Lacoste", titleTail: "— Experience Ceremony",
    intro: "A brand event that had to feel like Lacoste in a new world — sport, elegance and innovation blended into one coherent, premium moment, from the invite to the room.",
    meta: [["Client", "Lacoste"], ["Sector", "Fashion & Sport"], ["Services", "Event identity · Visual direction"], ["Role", "Concept & Visual Sprint"], ["Year", "2025"]],
    heroImg: "assets/work/lacoste/ball.png", heroScale: 1.06, heroBg: "linear-gradient(135deg, #16241a, #050806)", heroFig: "Fig. 03 — Lacoste",
    brief: ["A strong idea with no defined visual world. The event risked looking like a ", "generic premium template", " — so we set the direction before anything was produced: sport, elegance, innovation."],
    transformation: [
      ["Before", "A powerful concept with no visual language — every touchpoint would have been improvised, off-brand and forgettable."],
      ["The system", "One event identity: the crocodile as hero, a green-and-cream palette, screen language and credentials that all speak together."],
      ["After", "A ceremony that felt unmistakably Lacoste in a new world — coherent from the invite to the stage to the lanyard."],
    ],
    steps: [
      { n: "01", t: "Direction", d: "We locked the world in a Visual Sprint — sport, elegance, innovation — before a single asset was produced." },
      { n: "02", t: "Identity", d: "The crocodile leads: a green-and-cream system, refined type and a confident, premium tone." },
      { n: "03", t: "The room", d: "Stage screen, seating and spatial graphics designed as one continuous brand moment." },
      { n: "04", t: "Touchpoints", d: "Credentials, lanyards and signage — every detail on-brand, down to the badge." },
      { n: "05", t: "Motion", d: "Animated brand banners and screen content that keep the identity alive through the event." },
    ],
    moodboardImg: "assets/work/lacoste/moodboard.png?v=3",
    gallery: [
      ["assets/work/lacoste/stage.jpg", "On the big screen", "Sport, elegance, innovation", "The stage became the statement — the wordmark and crocodile at architectural scale, flanked by campaign imagery, so the room read as Lacoste the moment the lights came up."],
      ["assets/work/lacoste/campaign.png", "Out on court", "Barcelona Open · Banc Sabadell"],
      ["assets/work/lacoste/credentials.jpg", "Access all areas", "Credentials & lanyards, on-brand"],
    ],
    quote: ["Lacoste in a new world — ", "not a stock interpretation of it."],
    results: [{ to: 100, suffix: "%", label: "on-brand, invite to stage to lanyard" }, { to: 5, suffix: "", label: "sprint phases, briefing to delivery" }, { to: 1, suffix: "", label: "coherent world, every touchpoint" }],
    deliverBlurb: "One event world the team could extend — from the screen to the room to the smallest credential.",
    deliverables: ["Event identity", "Stage & screen language", "Spatial graphics", "Credentials & lanyards", "Motion banners", "Direction guidelines"],
    next: { label: "Lazura — Investor Pitch System", slug: "lazura" },
  },
  "cafe-vision": {
    badge: "Case study",
    title: "Café Vision", titleTail: "— Brand Launch System",
    intro: "A conceptual specialty coffee brand for a new generation of urban coffee drinkers — people who see coffee as a ritual for focus, clarity and creative thinking. From concept to launch-ready visual system.",
    meta: [["Client", "Café Vision"], ["Sector", "Specialty Coffee"], ["Services", "Brand identity · Launch system"], ["Location", "Geneva"], ["Year", "2025"]],
    heroImg: "assets/work/cafe-vision-facade.jpg", heroScale: 1.02, heroBg: "linear-gradient(135deg, #0D47A1, #0F1B2E)", heroFig: "Fig. 02 — Café Vision · Genève",
    brief: ["Café Vision needed more than a logo. The real question was not how the logo should look — it was ", "how the whole brand should feel every time someone sees it", ", across coffee bags, cups, menus, signage, web and launch."],
    transformation: [
      ["Before", "The project existed as an idea: specialty coffee, creative focus, a premium urban café — but no visual system to make it feel real, coherent and ready to launch."],
      ["The idea", "Clarity in every cup. Not just coffee — the small ritual that helps people start, focus and think better. One point of view shaping every decision."],
      ["After", "A complete launch-ready brand. Distinctive packaging, a strong digital campaign direction, a connected retail world — every touchpoint speaking the same language."],
    ],
    steps: [
      { n: "01", t: "Concept refinement", d: "Sharpen the positioning: premium but not cold, playful but not childish, distinctive against beige-minimal specialty-coffee clichés." },
      { n: "02", t: "Identity direction", d: "A bold, rounded wordmark — modern, warm and instantly recognisable — that avoids refined serifs and generic coffee icons for a contemporary personality." },
      { n: "03", t: "Colour & type system", d: "An expressive palette inspired by Geneva and modern retail — deep blue, bottle green, warm cream, coffee black and a vivid citrus accent — with structured, legible typography." },
      { n: "04", t: "Packaging & touchpoints", d: "A flexible system for coffee bags, cups, labels and retail objects, using the logo as a strong graphic signature while keeping product information clean." },
      { n: "05", t: "Launch & retail", d: "Signage, menu boards, tote bags, posters, web and social — all connected by one visual language, launch-ready across every surface." },
    ],
    quote: ["Clarity ", "in every cup."],
    results: [{ to: 14, suffix: "", label: "connected touchpoints, one visual system" }, { to: 6, suffix: "", label: "colour palette built for rhythm across formats" }, { to: 1, suffix: "", label: "recognisable world, cup to storefront" }],
    deliverBlurb: "One idea becoming many connected formats — a coffee bag, a storefront, a website, a campaign, a menu, a tote. Different surfaces, one visual system.",
    deliverables: ["Brand concept & idea", "Logo & wordmark", "Colour palette", "Typography direction", "Packaging system", "Web & social direction", "Retail signage & menus", "Merch & launch assets"],
    palette: [["#0D47A1", "Deep blue"], ["#009688", "Bottle green"], ["#C6E600", "Citrus"], ["#FF6F4D", "Coral"], ["#F7F2E9", "Cream"], ["#0F1B2E", "Coffee black"]],
    moodboardImg: "assets/work/cafe-vision-system.png",
    gallery: [["assets/work/cafe-vision-packaging.jpg", "Packaging family", "Eleven touchpoints, one shelf presence"], ["assets/work/cafe-vision-poster.jpg", "Out in Genève", "The brand, live on the street", "From a 250g pouch on a shelf to a tram-stop poster on the Rive, Café Vision keeps one voice — the same wordmark, the same palette, the same calm confidence. That consistency is what makes a young brand feel established from day one."]],
    next: { label: "Lacoste — Experience Ceremony", slug: "lacoste" },
  },
};

function LxReveal({ children, clip, style }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    let done = false;
    const show = () => { if (!done) { done = true; el.classList.add("in"); } };
    const io = new IntersectionObserver((es) => es.forEach(e => { if (e.isIntersecting) { show(); io.disconnect(); } }), { threshold: 0.01 });
    io.observe(el);
    const t = setTimeout(show, 1600); // safety: never leave content hidden
    return () => { io.disconnect(); clearTimeout(t); };
  }, []);
  return <div ref={ref} className={clip ? "lx-clip" : "lx-rise"} style={style}>{children}</div>;
}

function FeedBand({ src, alt }) {
  const wrapRef = React.useRef(null);
  const imgRef = React.useRef(null);
  React.useEffect(() => {
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
    let raf = null;
    const update = () => {
      raf = null;
      const el = wrapRef.current, im = imgRef.current; if (!el || !im) return;
      const r = el.getBoundingClientRect();
      const vh = window.innerHeight || 1;
      const p = Math.max(0, Math.min(1, (vh - r.top) / (vh + r.height)));
      // image is taller than the band; slide it fully across as you scroll
      const travel = im.offsetHeight - el.offsetHeight;
      im.style.transform = "translateY(" + (-p * travel) + "px)";
    };
    const onScroll = () => { if (raf == null) raf = requestAnimationFrame(update); };
    update();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    const t = setTimeout(update, 300);
    return () => { window.removeEventListener("scroll", onScroll); window.removeEventListener("resize", onScroll); if (raf) cancelAnimationFrame(raf); clearTimeout(t); };
  }, []);
  return (
    <div ref={wrapRef} style={{ position: "relative", height: "clamp(200px,24vw,320px)", borderRadius: "var(--radius-lg)", overflow: "hidden", border: "1px solid rgba(244,244,239,.12)", background: "#0b0f0c" }}>
      <img ref={imgRef} src={src} alt={alt} draggable="false" style={{ position: "absolute", top: 0, left: 0, width: "100%", height: "auto", willChange: "transform" }} />
    </div>
  );
}

function EventMontage() {
  const wrapRef = React.useRef(null);
  const layerRefs = React.useRef([]);
  const headRef = React.useRef(null);
  // scattered cropped shots that assemble over the feed as you scroll
  const shots = [
    { src: "ev-photocall.png?v=3", top: "6%", left: "4%", w: "34%", rot: -5, depth: 34, tag: "Photocall" },
    { src: "ev-entrance.png?v=3", top: "2%", left: "58%", w: "38%", rot: 4, depth: 60, tag: "Doors open" },
    { src: "ev-cocktail.png?v=3", top: "62%", left: "24%", w: "44%", rot: -2, depth: 20, tag: "The room" },
    { src: "ev-stage.png?v=3", top: "52%", left: "62%", w: "36%", rot: 6, depth: 78, tag: "Keynote" },
    { src: "ev-cocktail2.png?v=3", top: "58%", left: "2%", w: "30%", rot: 5, depth: 46, tag: "Cheers" },
  ];
  React.useEffect(() => {
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
      layerRefs.current.forEach(l => { if (l) { l.style.opacity = 1; l.style.transform = "none"; } });
      return;
    }
    let raf = null;
    const update = () => {
      raf = null;
      const el = wrapRef.current; if (!el) return;
      const r = el.getBoundingClientRect();
      const vh = window.innerHeight || 1;
      const p = Math.max(0, Math.min(1, (vh - r.top) / (vh + r.height)));
      layerRefs.current.forEach((l, i) => {
        if (!l) return;
        const d = shots[i].depth;
        const appear = Math.max(0, Math.min(1, (p - 0.08 - i * 0.06) / 0.28));
        const y = (0.5 - p) * d + (1 - appear) * 60;
        l.style.opacity = appear;
        l.style.transform = "translateY(" + y + "px) rotate(" + shots[i].rot + "deg) scale(" + (0.92 + appear * 0.08) + ")";
      });
      if (headRef.current) {
        const fade = Math.max(0, Math.min(1, (p - 0.4) / 0.16));
        headRef.current.style.opacity = 1 - fade;
        headRef.current.style.transform = "translateY(" + (-fade * 40) + "px)";
      }
    };
    const onScroll = () => { if (raf == null) raf = requestAnimationFrame(update); };
    update();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    return () => { window.removeEventListener("scroll", onScroll); window.removeEventListener("resize", onScroll); if (raf) cancelAnimationFrame(raf); };
  }, []);
  return (
    <div ref={wrapRef} style={{ position: "relative", width: "100vw", marginLeft: "calc(50% - 50vw)", height: "min(126vh, 1260px)", marginTop: "clamp(24px,3vw,44px)", overflow: "hidden", background: "radial-gradient(120% 80% at 50% 30%, #10231a, #06080b 70%)" }}>
      <div aria-hidden="true" style={{ position: "absolute", inset: 0, backgroundImage: "linear-gradient(rgba(244,244,239,.045) 1px, transparent 1px), linear-gradient(90deg, rgba(244,244,239,.045) 1px, transparent 1px)", backgroundSize: "60px 60px", opacity: .5, pointerEvents: "none" }} />
      {/* sticky headline */}
      <div style={{ position: "sticky", top: 0, height: "min(100vh, 1000px)", display: "flex", alignItems: "center", justifyContent: "center", pointerEvents: "none" }}>
        <div ref={headRef} style={{ textAlign: "center", zIndex: 1, willChange: "opacity, transform" }}>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".24em", textTransform: "uppercase", color: "var(--lime-500)" }}>The night itself</span>
          <h2 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(44px,8vw,132px)", lineHeight: .94, letterSpacing: "-0.02em", margin: "clamp(14px,2vw,24px) 0 0", color: "var(--paper)" }}>The room<br/><span style={{ fontStyle: "italic", color: "var(--lime-500)" }}>came alive.</span></h2>
        </div>
        {/* montage layers */}
        {shots.map((s, i) => (
          <div key={s.src} ref={(el) => (layerRefs.current[i] = el)} style={{ position: "absolute", top: s.top, left: s.left, width: s.w, opacity: 0, willChange: "transform, opacity", zIndex: s.depth > 40 ? 3 : 2 }}>
            <div style={{ position: "relative", borderRadius: 8, overflow: "hidden", border: "1px solid rgba(244,244,239,.16)", boxShadow: "0 40px 80px -34px rgba(0,0,0,.7)" }}>
              <img src={"assets/work/lacoste/" + s.src} alt={s.tag} draggable="false" style={{ display: "block", width: "100%", height: "auto" }} />
              <span style={{ position: "absolute", left: 12, bottom: 10, fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: ".14em", textTransform: "uppercase", color: "rgba(244,244,239,.9)", textShadow: "0 1px 6px rgba(0,0,0,.7)" }}>{s.tag}</span>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

function LacosteCase({ d }) {
  const { Button, Eyebrow } = VW_NS;
  const EASE = "cubic-bezier(.16,1,.3,1)";
  return (
    <main data-theme="dark" style={{ background: "#06080b" }}>
      {/* top bar */}
      <div style={{ maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "28px var(--page-margin) 0" }}>
        <a href="#" onClick={(e) => { e.preventDefault(); window.DH_NAV("work"); }} style={{ fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".1em", textTransform: "uppercase", color: "rgba(244,244,239,.55)" }}>← All work</a>
      </div>

      {/* CINEMATIC HERO — full-bleed ball, title overlaid */}
      <section style={{ position: "relative", width: "100vw", marginLeft: "calc(50% - 50vw)", height: "min(92vh, 920px)", overflow: "hidden", marginTop: 20 }}>
        <img src="assets/work/lacoste-court-hero.jpg?v=3" alt="Lacoste" className="lx-kb" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", objectPosition: "center 42%", transformOrigin: "center" }} />
        <div style={{ position: "absolute", inset: 0, background: "linear-gradient(to top, #06080b 3%, rgba(6,8,11,.25) 40%, rgba(6,8,11,.55) 100%)" }} />
        <div style={{ position: "absolute", inset: 0, maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "0 var(--page-margin)", display: "flex", flexDirection: "column", justifyContent: "flex-end", paddingBottom: "clamp(40px,6vw,88px)" }}>
          <span style={{ display: "inline-flex", alignItems: "center", gap: 12, fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".22em", textTransform: "uppercase", color: "var(--lime-500)" }}><span style={{ width: 24, height: 2, background: "var(--lime-500)" }} />Experience Ceremony · 2025</span>
          <h1 className="dh-sv-p" style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(52px,9vw,150px)", lineHeight: .92, letterSpacing: "-0.02em", margin: "clamp(18px,2vw,28px) 0 0", color: "var(--paper)" }}>Lacoste,<br/><span style={{ color: "var(--lime-500)" }}>staged.</span></h1>
          <p className="dh-sv-p" style={{ fontFamily: "var(--font-sans)", fontSize: "clamp(17px,1.5vw,21px)", lineHeight: 1.55, color: "rgba(244,244,239,.82)", margin: "clamp(20px,2vw,30px) 0 0", maxWidth: "52ch" }}>An event that had to feel unmistakably Lacoste in a new world. We built the whole world — sport, elegance, innovation — from the invite to the stage to the smallest credential.</p>
        </div>
      </section>

      {/* META STRIP — event ticket feel */}
      <section style={{ maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "clamp(36px,4vw,56px) var(--page-margin)" }}>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 20, borderTop: "1px solid rgba(244,244,239,.14)", borderBottom: "1px solid rgba(244,244,239,.14)", padding: "clamp(20px,2vw,28px) 0" }}>
          {d.meta.map(([k, v]) => (
            <div key={k}>
              <div style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: ".16em", textTransform: "uppercase", color: "var(--lime-500)", marginBottom: 10 }}>{k}</div>
              <div style={{ fontFamily: "var(--font-sans)", fontSize: 15, lineHeight: 1.35, color: "var(--paper)" }}>{v}</div>
            </div>
          ))}
        </div>
      </section>

      {/* STATEMENT */}
      <section style={{ maxWidth: "var(--maxw-content)", margin: "0 auto", padding: "clamp(20px,3vw,52px) var(--page-margin) var(--section-y)" }}>
        <div style={{ display: "grid", gridTemplateColumns: "0.3fr 0.7fr", gap: "clamp(24px,4vw,64px)", alignItems: "start" }}>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".2em", textTransform: "uppercase", color: "var(--lime-500)" }}>The brief</span>
          <p style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(24px,2.8vw,42px)", lineHeight: 1.2, letterSpacing: "-0.01em", margin: 0, color: "var(--paper)" }}>A strong idea with no visual world. The event risked looking like a <span style={{ color: "rgba(244,244,239,.4)" }}>generic premium template</span> — so we set the direction first: <span style={{ color: "var(--lime-500)" }}>sport, elegance, innovation.</span></p>
        </div>
      </section>

      {/* THE WORLD — moodboard full-bleed */}
      <section style={{ marginBottom: "var(--section-y)" }}>
        <div style={{ maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "0 var(--page-margin)" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: "clamp(24px,3vw,36px)" }}>
            <span style={{ width: 18, height: 2, background: "var(--lime-500)" }} />
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".2em", textTransform: "uppercase", color: "var(--lime-500)" }}>The world we built</span>
          </div>
        </div>
        <MoodParallax src="assets/work/lacoste/merch.png?v=3" alt="Lacoste — event collateral" />
      </section>

      {/* THE ROOM — immersive stage with typed line */}
      <ImmersivePoster src="assets/work/lacoste/stage.jpg" text="The stage became the statement — the wordmark and the crocodile at architectural scale, so the room read as Lacoste the moment the lights came up." />

      {/* THE COLLATERAL — editorial grid of event pieces */}
      <section style={{ maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "var(--section-y) var(--page-margin)" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: "clamp(28px,3vw,44px)" }}>
          <span style={{ width: 18, height: 2, background: "var(--lime-500)" }} />
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".2em", textTransform: "uppercase", color: "var(--lime-500)" }}>Every touchpoint, on-brand</span>
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "clamp(16px,2vw,28px)" }}>
          {[
            ["bags.png?v=3", "01", "The gift · tote & shopper", "16 / 9"],
            ["badges.png?v=3", "02", "Access · participant, staff, VIP", "16 / 9"],
            ["programme.png?v=3", "03", "The programme · agenda & venue", "16 / 9"],
            ["signage.png?v=3", "04", "Wayfinding · the room, signed", "16 / 9"],
          ].map(([img, n, cap, ar]) => (
            <LxReveal key={img} clip style={{ margin: 0 }}>
              <figure style={{ margin: 0 }}>
              <div style={{ aspectRatio: ar, borderRadius: "var(--radius-lg)", overflow: "hidden", border: "1px solid rgba(244,244,239,.12)", background: "#e9e6df" }}>
                <img src={"assets/work/lacoste/" + img} alt={cap} style={{ width: "100%", height: "100%", objectFit: "cover" }} />
              </div>
              <figcaption style={{ display: "flex", alignItems: "baseline", gap: 10, marginTop: 14 }}><span style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--lime-500)" }}>{n}</span><span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".08em", textTransform: "uppercase", color: "rgba(244,244,239,.6)" }}>{cap}</span></figcaption>
              </figure>
            </LxReveal>
          ))}
        </div>
        {/* social — narrow parallax band, reveals full mockup on scroll */}
        <div style={{ marginTop: "clamp(16px,2vw,28px)" }}>
          <FeedBand src="assets/work/lacoste/social.png" alt="Lacoste — social campaign" />
          <div style={{ display: "flex", alignItems: "baseline", gap: 10, marginTop: 14 }}><span style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--lime-500)" }}>05</span><span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".08em", textTransform: "uppercase", color: "rgba(244,244,239,.6)" }}>Live on the feed · countdown, invite, BTS</span></div>
        </div>
      </section>

      {/* THE NIGHT — scroll-assembled event montage */}
      <EventMontage />

      {/* THE IDENTITY SYSTEM — palette + type spec band */}
      <section style={{ maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "0 var(--page-margin) var(--section-y)" }}>
        <div style={{ display: "grid", gridTemplateColumns: "0.8fr 1.2fr", gap: "clamp(28px,4vw,72px)", alignItems: "start", borderTop: "1px solid rgba(244,244,239,.12)", paddingTop: "clamp(36px,4vw,60px)" }}>
          <div>
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".2em", textTransform: "uppercase", color: "var(--lime-500)" }}>The identity system</span>
            <p style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(22px,2.4vw,34px)", lineHeight: 1.2, letterSpacing: "-0.01em", margin: "18px 0 0", color: "var(--paper)", maxWidth: "16ch" }}>One palette, one voice — the crocodile leads.</p>
          </div>
          <div>
            {/* palette */}
            <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 2, borderRadius: "var(--radius-md)", overflow: "hidden" }}>
              {[["#1F4D2E", "Court Green", "PMS 3435"], ["#EFEBE0", "Chalk", "Off-white"], ["#0B1F14", "Deep Pine", "Ink"], ["#0A0A0B", "Baseline", "Black"]].map(([hex, name, ref]) => (
                <div key={hex} style={{ background: hex, aspectRatio: "3 / 4", position: "relative", border: "1px solid rgba(244,244,239,.08)" }}>
                  <div style={{ position: "absolute", left: 12, bottom: 12 }}>
                    <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".04em", color: hex === "#EFEBE0" ? "#1F4D2E" : "rgba(244,244,239,.92)" }}>{name}</div>
                    <div style={{ fontFamily: "var(--font-mono)", fontSize: 9.5, letterSpacing: ".08em", textTransform: "uppercase", color: hex === "#EFEBE0" ? "rgba(31,77,46,.6)" : "rgba(244,244,239,.5)", marginTop: 4 }}>{hex} · {ref}</div>
                  </div>
                </div>
              ))}
            </div>
            {/* type spec */}
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", gap: 24, flexWrap: "wrap", marginTop: 22, paddingTop: 22, borderTop: "1px solid rgba(244,244,239,.12)" }}>
              <div>
                <span style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(40px,5vw,72px)", lineHeight: .9, color: "var(--paper)" }}>Aa</span>
                <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".1em", textTransform: "uppercase", color: "rgba(244,244,239,.55)", marginTop: 10 }}>Display · headlines</div>
              </div>
              <div>
                <span style={{ fontFamily: "var(--font-sans)", fontWeight: 700, fontSize: "clamp(34px,4vw,58px)", lineHeight: .9, color: "var(--paper)" }}>Aa</span>
                <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".1em", textTransform: "uppercase", color: "rgba(244,244,239,.55)", marginTop: 10 }}>Grotesk · signage</div>
              </div>
              <img src="assets/logos/deckhaus-mark-lime.svg" alt="" style={{ height: 40, opacity: .5 }} />
            </div>
          </div>
        </div>
      </section>

      {/* MOTION BANNERS — animated band */}
      <section style={{ width: "100vw", marginLeft: "calc(50% - 50vw)", borderTop: "1px solid rgba(244,244,239,.12)", borderBottom: "1px solid rgba(244,244,239,.12)" }}>
        <img src="assets/work/lacoste/banner1.gif" alt="Lacoste motion banner" style={{ display: "block", width: "100%", height: "auto", borderBottom: "1px solid rgba(244,244,239,.1)" }} />
        <img src="assets/work/lacoste/banner2.gif" alt="Lacoste motion banner" style={{ display: "block", width: "100%", height: "auto" }} />
      </section>

      {/* PROCESS + RESULTS */}
      <section style={{ maxWidth: "var(--maxw-content)", margin: "0 auto", padding: "var(--section-y) var(--page-margin)" }}>
        <Eyebrow>How it came together</Eyebrow>
        <div style={{ marginTop: 36 }}>
          {d.steps.map((s) => (
            <div key={s.n} style={{ display: "grid", gridTemplateColumns: "72px 0.8fr 1.4fr", gap: "clamp(18px,2.4vw,36px)", padding: "clamp(24px,2.4vw,32px) 0", borderTop: "1px solid rgba(244,244,239,.12)", alignItems: "baseline" }}>
              <span style={{ fontFamily: "var(--font-mono)", fontSize: 14, color: "var(--lime-500)" }}>{s.n}</span>
              <h3 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(21px,2vw,28px)", lineHeight: 1.12, letterSpacing: "-0.01em", margin: 0, color: "var(--paper)" }}>{s.t}</h3>
              <p style={{ color: "rgba(244,244,239,.66)", fontSize: 16, lineHeight: 1.62, margin: 0, maxWidth: "50ch" }}>{s.d}</p>
            </div>
          ))}
        </div>
        <figure style={{ margin: "clamp(56px,8vw,120px) 0", textAlign: "center" }}>
          <blockquote style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(34px,6vw,84px)", lineHeight: 1.04, letterSpacing: "-0.02em", margin: 0, color: "var(--paper)", maxWidth: "18ch", marginInline: "auto", textWrap: "balance" }}>{d.quote[0]}<span style={{ fontStyle: "italic", color: "var(--lime-500)" }}>{d.quote[1]}</span></blockquote>
        </figure>
        <div className="dh-mstack" style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: "clamp(24px,3vw,56px)", paddingTop: 40, borderTop: "1px solid rgba(244,244,239,.12)" }}>
          {d.results.map((r, k) => (
            <div key={k}>
              <div style={{ display: "flex", alignItems: "baseline" }}>
                <span style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(50px,7vw,100px)", lineHeight: .82, letterSpacing: "-0.02em", color: "var(--paper)" }}><CU to={r.to} /></span>
                {r.suffix ? <span style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(34px,4.4vw,64px)", lineHeight: .9, color: "var(--lime-500)" }}>{r.suffix}</span> : null}
              </div>
              <span style={{ display: "block", fontFamily: "var(--font-mono)", fontSize: 12.5, letterSpacing: ".04em", color: "rgba(244,244,239,.6)", marginTop: 16, maxWidth: "22ch" }}>{r.label}</span>
            </div>
          ))}
        </div>
      </section>

      {/* NEXT / CTA */}
      <section style={{ borderTop: "1px solid rgba(244,244,239,.12)" }}>
        <div style={{ maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "var(--section-y) var(--page-margin)", display: "flex", justifyContent: "space-between", alignItems: "flex-end", gap: 32, flexWrap: "wrap" }}>
          <div>
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".2em", textTransform: "uppercase", color: "rgba(244,244,239,.5)" }}>Next case</span>
            <a href="#" onClick={(e) => { e.preventDefault(); window.DH_NAV("case", d.next.slug); }} style={{ display: "block", fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(30px,4.4vw,60px)", lineHeight: 1.04, letterSpacing: "-0.01em", margin: "16px 0 0", color: "var(--paper)", textDecoration: "none" }}>{d.next.label} →</a>
          </div>
          <Button size="lg" onClick={() => window.DH_NAV("contact")} trailingIcon={<window.ArrowR/>}>Start your sprint</Button>
        </div>
      </section>
    </main>
  );
}

function CaseStudyView() {
  const { Badge, Button, Eyebrow } = VW_NS;
  const d = CASE_DATA[window.DH_CASE] || CASE_DATA["lacoste"];
  if (window.DH_CASE === "lacoste") return <LacosteCase d={d} />;
  return (
    <main>
      {/* top bar */}
      <div style={{ maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "32px var(--page-margin) 0" }}>
        <a href="#" onClick={(e) => { e.preventDefault(); window.DH_NAV("work"); }} style={{ fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".1em", textTransform: "uppercase", color: "var(--text-muted)" }}>← All work</a>
      </div>

      {/* hero */}
      <div style={{ maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "28px var(--page-margin) clamp(36px,4vw,56px)" }}>
        <span style={{ display: "inline-flex", alignItems: "center", gap: 12, fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".24em", textTransform: "uppercase", color: "var(--lime-500)" }}><span style={{ width: 22, height: 2, background: "var(--lime-500)", flex: "none" }} />{d.badge}</span>
        <h1 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(44px,7vw,96px)", lineHeight: 1.03, letterSpacing: "-0.015em", margin: "clamp(24px,2.6vw,36px) 0 0", maxWidth: "16ch", textWrap: "balance" }}>{d.title} <span style={{ color: "var(--text-muted)" }}>{d.titleTail}</span></h1>
        <p style={{ color: "var(--text-secondary)", fontSize: "clamp(17px,1.4vw,20px)", lineHeight: 1.6, maxWidth: "56ch", margin: "clamp(24px,2.4vw,34px) 0 0" }}>{d.intro}</p>
      </div>

      {/* meta bar */}
      <div style={{ maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "0 var(--page-margin) clamp(28px,3vw,44px)" }}>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 24, borderTop: "1px solid var(--border-default)", borderBottom: "1px solid var(--border-default)", padding: "clamp(20px,2vw,28px) 0" }}>
          {d.meta.map(([k, v]) => (
            <div key={k}>
              <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".16em", textTransform: "uppercase", color: "var(--text-muted)", marginBottom: 10 }}>{k}</div>
              <div style={{ fontFamily: "var(--font-sans)", fontSize: 15, lineHeight: 1.35, color: "var(--text-primary)" }}>{v}</div>
            </div>
          ))}
        </div>
      </div>

      {/* full-bleed hero visual */}
      <div style={{ maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "0 var(--page-margin)" }}>
        {d.deck ? (
          <DeckStack slides={d.deck.slides} bg={d.heroBg} fig={d.heroFig} />
        ) : (
        <div style={{ aspectRatio: "16 / 8", borderRadius: "var(--radius-xl)", overflow: "hidden", border: "1px solid var(--border-default)", background: d.heroBg, position: "relative" }}>
          <img src={d.heroImg} alt={d.title + " " + d.titleTail} style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", objectPosition: "center", transform: `scale(${d.heroScale})`, transformOrigin: "center" }} />
          <div style={{ position: "absolute", inset: 0, background: "linear-gradient(to top, rgba(8,10,8,.62) 2%, rgba(8,10,8,.06) 34%, rgba(8,10,8,.18) 100%)" }} />
          <span style={{ position: "absolute", left: "clamp(24px,2.6vw,40px)", top: "clamp(22px,2.2vw,34px)", zIndex: 2, fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".14em", textTransform: "uppercase", color: "rgba(244,244,239,.82)" }}>{d.heroFig}</span>
        </div>
        )}
      </div>

      {/* the brief — big statement */}
      <section style={{ maxWidth: "var(--maxw-content)", margin: "0 auto", padding: "var(--section-y) var(--page-margin) 0" }}>
        <div style={{ display: "grid", gridTemplateColumns: "0.32fr 0.68fr", gap: "clamp(28px,4vw,64px)", alignItems: "start" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
            <span style={{ width: 18, height: 2, background: "var(--lime-500)", flex: "none" }} />
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".2em", textTransform: "uppercase", color: "var(--text-accent)" }}>The brief</span>
          </div>
          <p style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(24px,2.8vw,40px)", lineHeight: 1.22, letterSpacing: "-0.01em", margin: 0, textWrap: "balance" }}>
            {d.brief[0]}<span style={{ color: "var(--text-muted)" }}>{d.brief[1]}</span>{d.brief[2]}
          </p>
        </div>
      </section>

      {/* the transformation — animated journey */}
      <section style={{ maxWidth: "var(--maxw-content)", margin: "0 auto", padding: "var(--section-y) var(--page-margin) 0" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", flexWrap: "wrap", gap: 16 }}>
          <Eyebrow>The transformation</Eyebrow>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--text-muted)" }}>Before → After</span>
        </div>
        <TransformationJourney items={d.transformation} slides={d.deck && d.deck.slides} palette={d.palette} />
      </section>

      {/* optional deck gallery */}
      {d.deck ? (
        <section style={{ maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "var(--section-y) var(--page-margin) 0" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: "clamp(28px,3vw,40px)" }}>
            <span style={{ width: 18, height: 2, background: "var(--lime-500)", flex: "none" }} />
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".2em", textTransform: "uppercase", color: "var(--text-accent)" }}>{d.deck.kicker}</span>
            <span style={{ flex: 1, height: 1, background: "var(--border-default)" }} />
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".06em", color: "var(--text-muted)" }}>{d.deck.note}</span>
          </div>
          <p style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(22px,2.4vw,34px)", lineHeight: 1.2, letterSpacing: "-0.01em", margin: "0 0 clamp(32px,4vw,48px)", maxWidth: "24ch" }}>{d.deck.blurb}</p>
          <LaptopDeck slides={d.deck.slides} />
        </section>
      ) : null}

      {/* optional component system */}
      {d.components ? (
        <section style={{ maxWidth: "var(--maxw-content)", margin: "0 auto", padding: "var(--section-y) var(--page-margin) 0" }}>
          <Eyebrow>{d.components.kicker}</Eyebrow>
          <p style={{ color: "var(--text-secondary)", fontSize: "clamp(17px,1.4vw,20px)", lineHeight: 1.6, margin: "22px 0 clamp(36px,4vw,52px)", maxWidth: "52ch" }}>{d.components.blurb}</p>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(2, 1fr)", gap: 0, borderTop: "1px solid var(--border-default)" }}>
            {d.components.items.map(([t, x], i) => (
              <div key={t} style={{ padding: "clamp(26px,2.8vw,38px) clamp(24px,2.4vw,40px) clamp(26px,2.8vw,38px) 0", borderBottom: "1px solid var(--border-default)", borderLeft: i % 2 === 1 ? "1px solid var(--border-default)" : "none", paddingLeft: i % 2 === 1 ? "clamp(24px,2.4vw,40px)" : 0 }}>
                <div style={{ display: "flex", alignItems: "baseline", gap: 12 }}>
                  <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--text-accent)" }}>{String(i + 1).padStart(2, "0")}</span>
                  <h3 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(21px,2vw,27px)", lineHeight: 1.1, letterSpacing: "-0.01em", margin: 0 }}>{t}</h3>
                </div>
                <p style={{ fontFamily: "var(--font-sans)", fontSize: 15.5, lineHeight: 1.6, color: "var(--text-secondary)", margin: "14px 0 0" }}>{x}</p>
              </div>
            ))}
          </div>
        </section>
      ) : null}

      {/* optional Claude workspace */}
      {d.claude ? (
        <section style={{ maxWidth: "var(--maxw-content)", margin: "0 auto", padding: "var(--section-y) var(--page-margin) 0" }}>
          <div data-theme="dark" style={{ position: "relative", overflow: "hidden", borderRadius: "var(--radius-xl)", border: "1px solid var(--border-default)", background: "linear-gradient(150deg, #1a1712, #0c0c0e 60%)", padding: "clamp(32px,4vw,64px)" }}>
            <div aria-hidden="true" style={{ position: "absolute", inset: 0, backgroundImage: "linear-gradient(rgba(217,119,87,.08) 1px, transparent 1px), linear-gradient(90deg, rgba(217,119,87,.08) 1px, transparent 1px)", backgroundSize: "48px 48px", pointerEvents: "none", WebkitMaskImage: "radial-gradient(120% 110% at 88% 0%, #000 18%, transparent 66%)", maskImage: "radial-gradient(120% 110% at 88% 0%, #000 18%, transparent 66%)" }} />
            <div style={{ position: "relative", display: "grid", gridTemplateColumns: "0.92fr 1.08fr", gap: "clamp(28px,4vw,64px)", alignItems: "center" }}>
              <div>
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".2em", textTransform: "uppercase", color: "var(--text-accent)" }}>{d.claude.kicker}</span>
                <h3 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(26px,3vw,42px)", lineHeight: 1.1, letterSpacing: "-0.015em", margin: "18px 0 0", color: "var(--paper)", maxWidth: "16ch" }}>From a prompt to an on-brand draft.</h3>
                <p style={{ color: "var(--text-secondary)", fontSize: 16.5, lineHeight: 1.62, margin: "20px 0 0", maxWidth: "44ch" }}>{d.claude.blurb}</p>
              </div>
              <ClaudeWorkspace prompts={d.claude.prompts} slides={d.deck && d.deck.slides} />
            </div>
          </div>
        </section>
      ) : null}

      {/* optional palette strip */}      {d.palette ? (
        <section style={{ maxWidth: "var(--maxw-content)", margin: "0 auto", padding: "var(--section-y) var(--page-margin) 0" }}>
          <Eyebrow>The palette</Eyebrow>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(6, 1fr)", gap: 0, marginTop: 32, borderRadius: "var(--radius-lg)", overflow: "hidden", border: "1px solid var(--border-default)" }}>
            {d.palette.map(([hex, name], i) => (
              <div key={hex} style={{ background: hex, aspectRatio: "3 / 4", position: "relative", borderLeft: i > 0 ? "1px solid rgba(0,0,0,.12)" : "none" }}>
                <div style={{ position: "absolute", left: 12, bottom: 12, right: 8 }}>
                  <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".08em", color: (hex === "#F7F2E9" || hex === "#C6E600") ? "rgba(15,27,46,.75)" : "rgba(255,255,255,.92)" }}>{hex}</div>
                  <div style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: ".1em", textTransform: "uppercase", color: (hex === "#F7F2E9" || hex === "#C6E600") ? "rgba(15,27,46,.5)" : "rgba(255,255,255,.6)", marginTop: 4 }}>{name}</div>
                </div>
              </div>
            ))}
          </div>
        </section>
      ) : null}

      {/* optional moodboard full-bleed */}
      {d.moodboardImg ? (
        <section style={{ maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "var(--section-y) var(--page-margin) 0" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 28 }}>
            <span style={{ width: 18, height: 2, background: "var(--lime-500)", flex: "none" }} />
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".2em", textTransform: "uppercase", color: "var(--text-accent)" }}>The system</span>
            <span style={{ flex: 1, height: 1, background: "var(--border-default)" }} />
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".06em", color: "var(--text-muted)" }}>Visual overview</span>
          </div>
          <MoodParallax src={d.moodboardImg} alt={d.title + " — visual system"} />
        </section>
      ) : null}

      {/* optional gallery — full-bleed showcase */}
      {d.gallery ? (
        <div>
          {d.gallery.map(([src, kicker, cap, desc], i) => (desc ? (
            <ImmersivePoster key={src} src={src} text={desc} />
          ) : (
            <section key={src} style={{ maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "var(--section-y) var(--page-margin) 0" }}>
              <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 28 }}>
                <span style={{ width: 18, height: 2, background: "var(--lime-500)", flex: "none" }} />
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".2em", textTransform: "uppercase", color: "var(--text-accent)" }}>{kicker}</span>
                <span style={{ flex: 1, height: 1, background: "var(--border-default)" }} />
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".06em", color: "var(--text-muted)" }}>{cap}</span>
              </div>
              <Reveal><MoodParallax src={src} alt={kicker} /></Reveal>
            </section>
          )))}
        </div>
      ) : null}

      {/* DARK STRETCH — process + quote + results */}
      <section data-theme="dark" style={{ background: "var(--bg-base)", marginTop: "var(--section-y)", borderTop: "1px solid var(--border-subtle)", borderBottom: "1px solid var(--border-subtle)", position: "relative", overflow: "hidden" }}>
        <div aria-hidden="true" className="dh-ftgrid" style={{ position: "absolute", inset: 0, backgroundImage: "linear-gradient(rgba(244,244,239,.045) 1px, transparent 1px), linear-gradient(90deg, rgba(244,244,239,.045) 1px, transparent 1px)", backgroundSize: "54px 54px", pointerEvents: "none", WebkitMaskImage: "radial-gradient(120% 70% at 15% 0%, #000 20%, transparent 70%)", maskImage: "radial-gradient(120% 70% at 15% 0%, #000 20%, transparent 70%)" }} />
        <div style={{ position: "relative", maxWidth: "var(--maxw-content)", margin: "0 auto", padding: "var(--section-y) var(--page-margin)" }}>
          <Eyebrow>The process</Eyebrow>
          <div style={{ marginTop: 36 }}>
            {d.steps.map((s) => (
              <div key={s.n} style={{ display: "grid", gridTemplateColumns: "80px 0.9fr 1.5fr", gap: "clamp(20px,2.4vw,36px)", padding: "clamp(26px,2.6vw,36px) 0", borderTop: "1px solid var(--border-subtle)", alignItems: "baseline" }}>
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 14, color: "var(--lime-500)" }}>{s.n}</span>
                <h3 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(22px,2vw,28px)", lineHeight: 1.14, letterSpacing: "-0.01em", margin: 0, color: "var(--paper)" }}>{s.t}</h3>
                <p style={{ color: "var(--text-secondary)", fontSize: 16, lineHeight: 1.62, margin: 0, maxWidth: "50ch" }}>{s.d}</p>
              </div>
            ))}
          </div>

          {/* pull quote — centered wow moment */}
          <figure style={{ margin: "clamp(64px,9vw,140px) 0", textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center" }}>
            <span aria-hidden="true" style={{ fontFamily: "var(--font-display)", fontSize: "clamp(60px,9vw,130px)", lineHeight: .4, color: "var(--lime-500)", height: "0.42em", display: "block" }}>“</span>
            <blockquote style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(38px,6.4vw,92px)", lineHeight: 1.04, letterSpacing: "-0.02em", margin: "clamp(28px,3vw,44px) 0 0", color: "var(--paper)", maxWidth: "16ch", textWrap: "balance" }}>
              {d.quote[0]}<span style={{ fontStyle: "italic", color: "var(--lime-500)" }}>{d.quote[1]}</span>
            </blockquote>
            <span aria-hidden="true" style={{ display: "block", width: 40, height: 1, background: "rgba(244,244,239,.3)", margin: "clamp(30px,3.4vw,46px) 0 0" }} />
            <figcaption style={{ marginTop: 20, fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: ".18em", textTransform: "uppercase", color: "var(--text-muted)" }}>Direction principle · Deckhaus</figcaption>
          </figure>

          {/* results */}
          <Eyebrow>The outcome</Eyebrow>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: "clamp(24px,3vw,56px)", marginTop: 40, paddingTop: 40, borderTop: "1px solid var(--border-subtle)" }}>
            {d.results.map((r, i) => (
              <div key={i}>
                <div style={{ display: "flex", alignItems: "baseline" }}>
                  <span style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(56px,7vw,104px)", lineHeight: .85, letterSpacing: "-0.02em", color: "var(--paper)" }}><CU to={r.to} /></span>
                  {r.suffix ? <span style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(40px,5vw,76px)", lineHeight: .85, color: "var(--lime-500)" }}>{r.suffix}</span> : null}
                </div>
                <span style={{ display: "block", fontFamily: "var(--font-mono)", fontSize: 13, letterSpacing: ".04em", color: "var(--text-secondary)", marginTop: 16, maxWidth: "22ch" }}>{r.label}</span>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* deliverables */}
      <section style={{ maxWidth: "var(--maxw-content)", margin: "0 auto", padding: "var(--section-y) var(--page-margin)" }}>
        <div style={{ display: "grid", gridTemplateColumns: "0.42fr 0.58fr", gap: "clamp(32px,4vw,72px)", alignItems: "start" }}>
          <div>
            <Eyebrow>What we delivered</Eyebrow>
            <p style={{ color: "var(--text-secondary)", fontSize: 17, lineHeight: 1.62, margin: "26px 0 0", maxWidth: "36ch" }}>{d.deliverBlurb}</p>
          </div>
          <ul style={{ listStyle: "none", margin: 0, padding: 0 }}>
            {d.deliverables.map((x, i) => (
              <li key={x} style={{ display: "flex", alignItems: "center", gap: 16, padding: "clamp(16px,1.6vw,22px) 0", borderTop: "1px solid var(--border-default)" }}>
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--text-muted)", width: 30, flex: "none" }}>{String(i + 1).padStart(2, "0")}</span>
                <span style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(20px,2vw,26px)", lineHeight: 1.15, letterSpacing: "-0.01em" }}>{x}</span>
              </li>
            ))}
          </ul>
        </div>
      </section>

      {/* next / CTA */}
      <section style={{ borderTop: "1px solid var(--border-default)" }}>
        <div style={{ maxWidth: "var(--maxw-wide)", margin: "0 auto", padding: "var(--section-y) var(--page-margin)", display: "flex", justifyContent: "space-between", alignItems: "flex-end", gap: 32, flexWrap: "wrap" }}>
          <div>
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, letterSpacing: ".2em", textTransform: "uppercase", color: "var(--text-muted)" }}>Next case</span>
            <a href="#" onClick={(e) => { e.preventDefault(); window.DH_NAV("case", d.next.slug); }} style={{ display: "block", fontFamily: "var(--font-display)", fontWeight: 400, fontSize: "clamp(32px,4.4vw,64px)", lineHeight: 1.04, letterSpacing: "-0.01em", margin: "18px 0 0", color: "var(--text-primary)", textDecoration: "none" }}>{d.next.label} →</a>
          </div>
          <Button size="lg" onClick={() => window.DH_NAV("contact")} trailingIcon={<window.ArrowR/>}>Start your sprint</Button>
        </div>
      </section>
    </main>
  );
}
