// Case study modal — UXCam Research (Delivery Confirmation App).
// Behavioural research → product hypothesis → in-app chat prototype.

const DL_ACCENT = '#FF5757';
const DL_BG = '#1A1010';
const DL_SURFACE = '#241616';
const DL_FG = '#F6EFE9';
const DL_MUTED = 'rgba(246,239,233,.65)';
const DL_DIM = 'rgba(246,239,233,.42)';
const DL_LINE = 'rgba(246,239,233,.12)';

// ── Atoms ────────────────────────────────────────────────────────────────────
const DLEyebrow = ({ children, color = DL_DIM }) => (
  <div style={{
    fontFamily: 'DM Sans, sans-serif', fontSize: 11,
    letterSpacing: '.22em', textTransform: 'uppercase',
    color, fontWeight: 600,
  }}>{children}</div>
);

const DLHeading = ({ children, size = 48, weight = 500, color = DL_FG, style }) => (
  <h2 style={{
    fontFamily: 'Libre Bodoni, serif', fontWeight: weight,
    fontSize: size, lineHeight: 1.05, letterSpacing: '-.02em',
    color, margin: 0, textWrap: 'balance', ...style,
  }}>{children}</h2>
);

const DLBody = ({ children, size = 16, color = DL_FG, opacity = .85, maxWidth = 640, style }) => (
  <p style={{
    fontFamily: 'DM Sans, sans-serif', fontSize: size, lineHeight: 1.6,
    color, opacity, margin: 0, maxWidth, textWrap: 'pretty', ...style,
  }}>{children}</p>
);

const DLSection = ({ children, py = 96, bg, style }) => (
  <section style={{ padding: `${py}px max(56px, 5vw)`, background: bg, ...style }}>{children}</section>
);

const DLReveal = ({ children, delay = 0, dir = 'up', style }) => {
  const ref = React.useRef(null);
  const [shown, setShown] = React.useState(false);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return undefined;
    if (typeof IntersectionObserver === 'undefined') { setShown(true); return undefined; }
    const io = new IntersectionObserver(
      (es) => es.forEach((e) => { if (e.isIntersecting) { setShown(true); io.disconnect(); } }),
      { threshold: 0.12, rootMargin: '0px 0px -8% 0px' }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);
  const offsets = { up: 'translateY(28px)', down: 'translateY(-22px)', left: 'translateX(-22px)', right: 'translateX(22px)', none: 'none' };
  return (
    <div ref={ref} style={{
      opacity: shown ? 1 : 0,
      transform: shown ? 'translate(0,0)' : offsets[dir] || offsets.up,
      transition: `opacity .8s cubic-bezier(.2,.7,.2,1) ${delay}ms, transform .9s cubic-bezier(.2,.7,.2,1) ${delay}ms`,
      ...style,
    }}>{children}</div>
  );
};

const DLPhone = ({ src, alt, width = 240, accent = DL_ACCENT, scrollable = false }) => (
  <div style={{
    width, position: 'relative',
    borderRadius: width * 0.13, background: '#0c0c0e', padding: width * 0.022,
    boxShadow: `inset 0 0 0 1.5px rgba(255,255,255,.12), 0 30px 60px -10px rgba(0,0,0,.55), 0 0 60px ${accent}11`,
  }}>
    <div style={{ position: 'absolute', left: -width * 0.012, top: width * 0.22, width: width * 0.012, height: width * 0.06, background: '#1a1a1c', borderRadius: 1 }} />
    <div style={{ position: 'absolute', left: -width * 0.012, top: width * 0.34, width: width * 0.012, height: width * 0.14, background: '#1a1a1c', borderRadius: 1 }} />
    <div style={{ position: 'absolute', right: -width * 0.012, top: width * 0.30, width: width * 0.012, height: width * 0.18, background: '#1a1a1c', borderRadius: 1 }} />
    <div style={{
      borderRadius: width * 0.105, overflow: scrollable ? 'auto' : 'hidden',
      background: '#fff', aspectRatio: '9 / 19.5', position: 'relative',
      scrollbarColor: `${accent} transparent`, scrollbarWidth: 'thin',
    }}>
      <img src={src} alt={alt} draggable={false}
           style={{
             display: 'block', width: '100%',
             height: scrollable ? 'auto' : '100%',
             objectFit: scrollable ? 'unset' : 'cover',
           }} />
    </div>
  </div>
);

// ── Hero ────────────────────────────────────────────────────────────────────
const DLHero = () => (
  <DLSection py={0} style={{ position: 'relative', paddingTop: 100, paddingBottom: 80 }}>
    <div className="dl-mesh" style={{
      position: 'absolute', inset: '8% -10% -10% -10%', pointerEvents: 'none', opacity: .85,
      background: `
        radial-gradient(50% 40% at 22% 30%, ${DL_ACCENT}26 0%, transparent 70%),
        radial-gradient(40% 35% at 78% 18%, #8E3A3A22 0%, transparent 70%),
        radial-gradient(60% 45% at 55% 85%, ${DL_ACCENT}1c 0%, transparent 65%)
      `,
    }} />

    <div style={{ position: 'relative', display: 'flex', flexDirection: 'column', gap: 48 }}>
      <DLReveal delay={50}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
          <DLEyebrow color={DL_ACCENT}>Case · 03</DLEyebrow>
          <span style={{ width: 32, height: 1, background: DL_LINE }} />
          <DLEyebrow>Logistics · Delivery confirmation</DLEyebrow>
        </div>
      </DLReveal>

      <DLReveal delay={120}>
        <DLHeading size={'clamp(64px, 8vw, 144px)'}>
          UXCam <span style={{ fontStyle: 'italic', color: DL_ACCENT }}>Research</span>
        </DLHeading>
      </DLReveal>

      <DLReveal delay={220}>
        <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr',
                       gap: 'clamp(40px, 5vw, 80px)', maxWidth: 1080, alignItems: 'start' }}>
          <DLBody size={20} maxWidth={620}>
            How a hunch about a hidden behaviour — couriers and customers trying to reach
            each other through the app — became a measurable problem, then a working
            solution. Driven by UXCam, validated in SQL Server, shipped as a chat.
          </DLBody>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, auto)', gap: '16px 48px' }}>
            {[
              ['Role',   'UX/UI Designer · Researcher'],
              ['Type',   'Behavioural research → product'],
              ['Methods', 'UXCam, SQL Server, prototyping'],
              ['Status',  'Prototype validated'],
            ].map(([k, v]) => (
              <div key={k} style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
                <DLEyebrow>{k}</DLEyebrow>
                <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 15, color: DL_FG }}>{v}</div>
              </div>
            ))}
          </div>
        </div>
      </DLReveal>

      {/* Hero composition — two phones at an angle + a delivery van glyph */}
      <DLReveal delay={300}>
        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center',
                       gap: 'clamp(40px, 6vw, 96px)', marginTop: 40, position: 'relative',
                       minHeight: 480 }}>
          {/* Left phone — old version */}
          <div style={{ transform: 'rotate(-9deg) translateY(8px)', zIndex: 2, position: 'relative' }}>
            <DLPhone src="case-assets/delivery/before.png" alt="Old delivery details screen" width={230} />
          </div>

          {/* Delivery van — sits between the two phones */}
          <div aria-hidden="true" style={{
            position: 'relative', zIndex: 3,
            display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14,
          }}>
            <svg width="160" height="110" viewBox="0 0 200 130" fill="none"
                 style={{ filter: `drop-shadow(0 18px 24px ${DL_ACCENT}33)`,
                          animation: 'dlVanRoll 4s ease-in-out infinite' }}>
              {/* Van body */}
              <rect x="6" y="40" width="126" height="56" rx="6" fill={DL_ACCENT} />
              {/* Cabin */}
              <path d="M132 60 L162 60 L182 80 L182 96 L132 96 Z" fill={DL_ACCENT} opacity="0.85" />
              <rect x="140" y="66" width="30" height="16" rx="2" fill={DL_BG} opacity="0.6" />
              {/* Door line */}
              <line x1="60" y1="40" x2="60" y2="96" stroke={DL_BG} strokeWidth="1.5" opacity="0.35" />
              {/* Wheels */}
              <circle cx="40" cy="100" r="12" fill="#1a0a0a" stroke={DL_FG} strokeWidth="3" />
              <circle cx="152" cy="100" r="12" fill="#1a0a0a" stroke={DL_FG} strokeWidth="3" />
              {/* Speed lines */}
              <line x1="-8" y1="50" x2="6" y2="50" stroke={DL_ACCENT} strokeWidth="2" strokeLinecap="round" opacity="0.7" />
              <line x1="-14" y1="68" x2="4" y2="68" stroke={DL_ACCENT} strokeWidth="2" strokeLinecap="round" opacity="0.5" />
              <line x1="-6" y1="86" x2="6" y2="86" stroke={DL_ACCENT} strokeWidth="2" strokeLinecap="round" opacity="0.3" />
              {/* Chat bubble glyph above van */}
              <circle cx="90" cy="22" r="16" fill={DL_FG} />
              <path d="M84 22 L84 22 M90 22 L90 22 M96 22 L96 22"
                    stroke={DL_BG} strokeWidth="2.5" strokeLinecap="round" />
              <path d="M78 30 L82 36 L84 32 Z" fill={DL_FG} />
            </svg>
            <div style={{
              fontFamily: 'DM Sans, sans-serif', fontSize: 10,
              letterSpacing: '.18em', textTransform: 'uppercase',
              color: DL_DIM, fontWeight: 600,
            }}>Before → after</div>
          </div>

          {/* Right phone — redesign */}
          <div style={{ transform: 'rotate(9deg) translateY(8px)', zIndex: 2, position: 'relative' }}>
            <DLPhone src="case-assets/delivery/parcel-redesign.png" alt="Redesigned parcel details with contact" width={230} />
          </div>
        </div>
      </DLReveal>
    </div>
  </DLSection>
);

// ── The hypothesis ──────────────────────────────────────────────────────────
const DLHypothesis = () => (
  <DLSection style={{ borderTop: `1px solid ${DL_LINE}` }}>
    <div style={{ maxWidth: 1280, display: 'grid', gridTemplateColumns: '1fr 1.4fr',
                   gap: 'clamp(48px, 6vw, 120px)', alignItems: 'start' }}>
      <DLReveal dir="left">
        <DLEyebrow>The hypothesis</DLEyebrow>
        <DLHeading size={'clamp(36px, 3.8vw, 56px)'} style={{ marginTop: 14 }}>
          Users want to <span style={{ color: DL_ACCENT, fontStyle: 'italic' }}>talk to each other.</span>
        </DLHeading>
      </DLReveal>
      <DLReveal dir="right" delay={120}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 22 }}>
          <DLBody size={18}>
            The product team kept hearing the same anecdote from support: couriers reaching
            out about parcel access codes, customers asking where the parcel actually was —
            but the app didn't have a chat. Yet.
          </DLBody>
          <DLBody size={18}>
            The hypothesis was uncomfortable: people were already doing it. They just used
            a comment field at the bottom of the parcel screen as a chat — a feature it was
            never meant to be.
          </DLBody>

          {/* Quote-like callout */}
          <div style={{
            marginTop: 18, padding: '24px 28px', borderRadius: 14,
            borderLeft: `2px solid ${DL_ACCENT}`,
            background: 'rgba(255,87,87,.06)',
          }}>
            <div style={{ fontFamily: 'Libre Bodoni, serif', fontStyle: 'italic',
                           fontSize: 22, lineHeight: 1.3, color: DL_FG, letterSpacing: '-.01em' }}>
              "Czy wejście do klatki jest wewnątrz osiedla czy na zewnątrz?"
            </div>
            <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 12,
                            letterSpacing: '.18em', textTransform: 'uppercase',
                            color: DL_MUTED, fontWeight: 600, marginTop: 12 }}>
              A real comment from October — being used as a question to the customer.
            </div>
          </div>
        </div>
      </DLReveal>
    </div>
  </DLSection>
);

// ── The before-state — visible only to a few ────────────────────────────────
const DLBefore = () => (
  <DLSection bg={DL_SURFACE} style={{ borderTop: `1px solid ${DL_LINE}`, borderBottom: `1px solid ${DL_LINE}` }}>
    <div style={{ maxWidth: 1280 }}>
      <DLReveal>
        <DLEyebrow>Before · the original</DLEyebrow>
        <DLHeading size={'clamp(36px, 3.8vw, 56px)'} style={{ marginTop: 14, marginBottom: 16, maxWidth: 880 }}>
          A comment field nobody was supposed to <span style={{ fontStyle: 'italic', color: DL_ACCENT }}>read like that.</span>
        </DLHeading>
        <DLBody size={17} opacity={.8} maxWidth={780} style={{ marginBottom: 48 }}>
          Couriers were typing real questions into the parcel "comment" field. The catch:
          the comment was only visible in an internal hub view — and even more clearly to
          analysts running SQL Server queries. The customer never saw most of them.
        </DLBody>
      </DLReveal>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 'clamp(40px, 5vw, 80px)',
                     alignItems: 'center' }}>
        <DLReveal dir="left">
          <div style={{ display: 'flex', justifyContent: 'center' }}>
            <DLPhone src="case-assets/delivery/before.png" alt="Old parcel details screen" width={260} />
          </div>
        </DLReveal>
        <DLReveal dir="right" delay={140}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 22 }}>
            {[
              ['Comments at the bottom', 'A small grey "comment" field below the parcel info. Built for one-line notes, used as a chat.'],
              ['Hub-only visibility', 'Only the internal hub view rendered the comments. The mobile customer rarely saw them.'],
              ['Analyst-grade discovery', 'The pattern was clearest in SQL Server: parcels with multiple comments, time-stamped minutes apart.'],
            ].map(([t, d]) => (
              <div key={t} style={{ display: 'flex', gap: 16, alignItems: 'flex-start' }}>
                <span style={{ width: 8, height: 8, borderRadius: '50%', background: DL_ACCENT,
                                 marginTop: 9, flexShrink: 0, boxShadow: `0 0 8px ${DL_ACCENT}` }} />
                <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                  <div style={{ fontFamily: 'Libre Bodoni, serif', fontSize: 22, fontWeight: 500,
                                  color: DL_FG, letterSpacing: '-.01em' }}>{t}</div>
                  <DLBody size={14.5} opacity={.75} maxWidth={460}>{d}</DLBody>
                </div>
              </div>
            ))}
          </div>
        </DLReveal>
      </div>
    </div>
  </DLSection>
);

// ── Research methodology ───────────────────────────────────────────────────
// Visual thinking process — two lenses converging on a single insight.
// No code snippets, no jargon, no invented keywords.
const DLResearch = () => (
  <DLSection style={{ borderTop: `1px solid ${DL_LINE}` }}>
    <div style={{ maxWidth: 1280 }}>
      <DLReveal>
        <DLEyebrow>How I proved it</DLEyebrow>
        <DLHeading size={'clamp(36px, 3.8vw, 56px)'} style={{ marginTop: 14, marginBottom: 18, maxWidth: 880 }}>
          Two lenses. <span style={{ fontStyle: 'italic', color: DL_ACCENT }}>One picture.</span>
        </DLHeading>
        <DLBody size={17} opacity={.78} maxWidth={760} style={{ marginBottom: 56 }}>
          Numbers tell us the size of a problem. Observation tells us its shape.
          I needed both — one to justify the work, the other to design for it.
        </DLBody>
      </DLReveal>

      <DLReveal delay={120}>
        <div style={{
          position: 'relative',
          borderRadius: 18,
          border: `1px solid ${DL_LINE}`,
          background: `radial-gradient(120% 80% at 50% 0%, ${DL_ACCENT}10 0%, transparent 60%), ${DL_SURFACE}`,
          padding: 'clamp(32px, 4vw, 56px)',
          overflow: 'hidden',
        }}>
          {/* Dotted connector lines linking the two lenses to the insight */}
          <svg viewBox="0 0 1000 480" preserveAspectRatio="none" aria-hidden="true"
               style={{ position: 'absolute', inset: 0, width: '100%', height: '100%',
                         pointerEvents: 'none', opacity: .35 }}>
            <path d="M 240 240 Q 380 320, 500 400" stroke={DL_ACCENT} strokeWidth="1.5"
                  fill="none" strokeDasharray="4 6" />
            <path d="M 760 240 Q 620 320, 500 400" stroke={DL_ACCENT} strokeWidth="1.5"
                  fill="none" strokeDasharray="4 6" />
          </svg>

          <div style={{ position: 'relative', display: 'grid',
                          gridTemplateColumns: '1fr 1fr', gap: 32 }}>
            {/* LENS 01 — Data: the scale */}
            <div style={{
              padding: 24, borderRadius: 14,
              border: `1px solid ${DL_LINE}`, background: 'rgba(0,0,0,.25)',
              display: 'flex', flexDirection: 'column', gap: 18,
            }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                <svg width="28" height="28" viewBox="0 0 24 24" fill="none" aria-hidden="true">
                  <ellipse cx="12" cy="6" rx="8" ry="3" stroke={DL_ACCENT} strokeWidth="1.6" />
                  <path d="M4 6v6c0 1.66 3.58 3 8 3s8-1.34 8-3V6" stroke={DL_ACCENT} strokeWidth="1.6" />
                  <path d="M4 12v6c0 1.66 3.58 3 8 3s8-1.34 8-3v-6" stroke={DL_ACCENT} strokeWidth="1.6" />
                </svg>
                <DLEyebrow color={DL_ACCENT}>Lens 01 · Data</DLEyebrow>
              </div>
              <DLHeading size={26}>The scale.</DLHeading>
              <DLBody size={14} opacity={.78} maxWidth={420}>
                I looked at one month of comments left on parcels. Where the same
                parcel collected more than one note, with short gaps between them,
                I treated it as a conversation in disguise.
              </DLBody>

              {/* Mini bar chart: distribution of comments per parcel */}
              <div style={{ display: 'flex', alignItems: 'flex-end', gap: 6,
                              height: 64, marginTop: 6 }}>
                {[18, 32, 46, 58, 70, 84, 96, 88, 72, 60, 44, 30].map((h, i) => (
                  <div key={i} style={{
                    flex: 1, height: `${h}%`,
                    background: i >= 4 && i <= 8 ? DL_ACCENT : 'rgba(246,239,233,.18)',
                    borderRadius: 2,
                    boxShadow: i >= 4 && i <= 8 ? `0 0 12px ${DL_ACCENT}55` : 'none',
                  }} />
                ))}
              </div>
              <div style={{ display: 'flex', justifyContent: 'space-between',
                              fontFamily: 'DM Sans, sans-serif', fontSize: 10,
                              letterSpacing: '.12em', textTransform: 'uppercase',
                              color: DL_DIM, fontWeight: 600 }}>
                <span>1 msg</span>
                <span style={{ color: DL_ACCENT }}>peak · 5–7 msgs</span>
                <span>12+</span>
              </div>
            </div>

            {/* LENS 02 — Observation: the shape */}
            <div style={{
              padding: 24, borderRadius: 14,
              border: `1px solid ${DL_LINE}`, background: 'rgba(0,0,0,.25)',
              display: 'flex', flexDirection: 'column', gap: 18,
            }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                <svg width="28" height="28" viewBox="0 0 24 24" fill="none" aria-hidden="true">
                  <path d="M2 12c2.5-5 6-7.5 10-7.5S19.5 7 22 12c-2.5 5-6 7.5-10 7.5S4.5 17 2 12z"
                        stroke={DL_ACCENT} strokeWidth="1.6" />
                  <circle cx="12" cy="12" r="3" stroke={DL_ACCENT} strokeWidth="1.6" />
                </svg>
                <DLEyebrow color={DL_ACCENT}>Lens 02 · Observation</DLEyebrow>
              </div>
              <DLHeading size={26}>The shape.</DLHeading>
              <DLBody size={14} opacity={.78} maxWidth={420}>
                I watched the recorded sessions for those parcels. Couriers opening
                the comment, leaving, coming back minutes later to read a reply.
                The motion was unmistakable — it was a chat.
              </DLBody>

              {/* Behaviour loop — 6 steps where one conversation should be enough */}
              <div style={{ marginTop: 6 }}>
                <svg width="100%" height="68" viewBox="0 0 320 68" aria-hidden="true">
                  {['Open', 'Type', 'Leave', 'Wait', 'Re-open', 'Read'].map((step, i) => {
                    const x = 20 + i * 56;
                    const isPeak = i === 4;
                    return (
                      <g key={step}>
                        {i < 5 && (
                          <path d={`M ${x + 6} 22 Q ${x + 28} ${i % 2 ? 4 : 40}, ${x + 50} 22`}
                                stroke={DL_ACCENT} strokeWidth="1.4" fill="none"
                                strokeDasharray="3 4" opacity="0.7" />
                        )}
                        <circle cx={x} cy="22" r={isPeak ? 7 : 5}
                                fill={isPeak ? DL_ACCENT : 'rgba(246,239,233,.18)'}
                                stroke={isPeak ? DL_ACCENT : DL_LINE} strokeWidth="1.4" />
                        <text x={x} y="56" textAnchor="middle"
                              fontFamily="DM Sans, sans-serif" fontSize="9"
                              fontWeight="600" letterSpacing="1"
                              fill={isPeak ? DL_FG : DL_MUTED}>{step.toUpperCase()}</text>
                      </g>
                    );
                  })}
                </svg>
              </div>
              <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 11,
                              color: DL_DIM, fontStyle: 'italic' }}>
                A loop where one conversation should have been enough.
              </div>
            </div>
          </div>

          {/* The convergence node */}
          <div style={{ position: 'relative', display: 'flex',
                          justifyContent: 'center', marginTop: 56 }}>
            <div style={{
              padding: '28px 36px', borderRadius: 16,
              border: `1px solid ${DL_ACCENT}55`,
              background: `radial-gradient(120% 100% at 50% 0%, ${DL_ACCENT}1f 0%, ${DL_BG} 80%)`,
              maxWidth: 640, textAlign: 'center',
              boxShadow: `0 24px 50px -10px rgba(0,0,0,.45), 0 0 60px ${DL_ACCENT}1a`,
            }}>
              <DLEyebrow color={DL_ACCENT}>The insight</DLEyebrow>
              <DLHeading size={'clamp(22px, 2.2vw, 30px)'} style={{ marginTop: 10 }}>
                Couriers and customers were already talking. The product just didn’t notice.
              </DLHeading>
            </div>
          </div>
        </div>
      </DLReveal>
    </div>
  </DLSection>
);

// ── Toolkit — UXCam + SQL Server as the named research stack ────────────────
// Sits between Hypothesis and Before. Names the tools clearly, says what each
// one did, without leaning on code snippets.
const DLToolkit = () => (
  <DLSection style={{ borderTop: `1px solid ${DL_LINE}` }}>
    <div style={{ maxWidth: 1280 }}>
      <DLReveal>
        <DLEyebrow>The research toolkit</DLEyebrow>
        <DLHeading size={'clamp(36px, 3.8vw, 56px)'} style={{ marginTop: 14, marginBottom: 18, maxWidth: 880 }}>
          Built on <span style={{ fontStyle: 'italic', color: DL_ACCENT }}>UXCam</span> and{' '}
          <span style={{ fontStyle: 'italic', color: DL_ACCENT }}>SQL Server.</span>
        </DLHeading>
        <DLBody size={17} opacity={.78} maxWidth={780} style={{ marginBottom: 56 }}>
          Two tools doing two different jobs — one to see the behaviour, one to size it.
          Together they turn a support anecdote into something a roadmap can act on.
        </DLBody>
      </DLReveal>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 32 }}>
        {/* UXCam */}
        <DLReveal dir="left">
          <div style={{
            position: 'relative',
            padding: 'clamp(28px, 3vw, 40px)',
            borderRadius: 18,
            border: `1px solid ${DL_LINE}`,
            background: `linear-gradient(180deg, ${DL_SURFACE} 0%, ${DL_BG} 100%)`,
            display: 'flex', flexDirection: 'column', gap: 24,
            overflow: 'hidden', minHeight: 360,
          }}>
            {/* Logo plate */}
            <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
              <div style={{
                width: 56, height: 56, borderRadius: 14,
                background: `radial-gradient(circle at 30% 30%, ${DL_ACCENT}, ${DL_ACCENT}aa)`,
                boxShadow: `0 0 32px ${DL_ACCENT}55, inset 0 0 0 1px rgba(255,255,255,.15)`,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>
                {/* Play / eye glyph */}
                <svg width="28" height="28" viewBox="0 0 24 24" fill="none" aria-hidden="true">
                  <path d="M2 12c2.5-5 6-7.5 10-7.5S19.5 7 22 12c-2.5 5-6 7.5-10 7.5S4.5 17 2 12z"
                        stroke="#fff" strokeWidth="1.8" />
                  <circle cx="12" cy="12" r="3" fill="#fff" />
                </svg>
              </div>
              <div>
                <DLEyebrow color={DL_ACCENT}>Behaviour</DLEyebrow>
                <div style={{ fontFamily: 'Libre Bodoni, serif', fontWeight: 500,
                                fontSize: 32, color: DL_FG, letterSpacing: '-.01em',
                                marginTop: 4, lineHeight: 1 }}>UXCam</div>
              </div>
            </div>

            <DLBody size={15} opacity={.82}>
              Session replays and heatmaps from the courier app. I watched how couriers
              actually used the comment field — opening it, leaving, coming back to read
              a reply. The motion told me it was already a chat.
            </DLBody>

            {/* Faux device frame with playhead bar */}
            <div style={{
              position: 'relative',
              marginTop: 'auto',
              borderRadius: 12,
              border: `1px solid ${DL_LINE}`,
              background: '#0e0606',
              padding: 16,
            }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10,
                              fontFamily: 'DM Sans, sans-serif', fontSize: 10,
                              letterSpacing: '.18em', textTransform: 'uppercase',
                              color: DL_DIM, fontWeight: 600, marginBottom: 12 }}>
                <span style={{ width: 8, height: 8, borderRadius: '50%', background: DL_ACCENT,
                                 boxShadow: `0 0 10px ${DL_ACCENT}`,
                                 animation: 'dlPulse 1.6s ease-in-out infinite' }} />
                Session · 04:32 / 26:04
              </div>
              {/* Timeline */}
              <div style={{ position: 'relative', height: 4, borderRadius: 999,
                              background: 'rgba(246,239,233,.12)' }}>
                {/* Event markers */}
                {[10, 22, 34, 58, 72].map((pct, i) => (
                  <div key={i} style={{
                    position: 'absolute', left: `${pct}%`, top: -3,
                    width: 10, height: 10, borderRadius: '50%',
                    background: DL_ACCENT, border: `2px solid ${DL_BG}`,
                    boxShadow: `0 0 8px ${DL_ACCENT}88`,
                  }} />
                ))}
                {/* Played portion */}
                <div style={{ position: 'absolute', left: 0, top: 0, bottom: 0,
                                width: '36%', background: DL_ACCENT, borderRadius: 999,
                                opacity: .8 }} />
              </div>
              <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 10,
                              fontFamily: 'DM Sans, sans-serif', fontSize: 10.5,
                              color: DL_MUTED }}>
                <span>Open parcel</span>
                <span style={{ color: DL_ACCENT }}>Re-open comment</span>
                <span>Confirm</span>
              </div>
            </div>

            <div style={{ display: 'flex', gap: 24, paddingTop: 18,
                            borderTop: `1px solid ${DL_LINE}` }}>
              {[
                ['Session replays', 'qualitative'],
                ['Heatmaps', 'on-screen behaviour'],
                ['Funnels', 'where users drop off'],
              ].map(([t, sub]) => (
                <div key={t}>
                  <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 12,
                                  color: DL_FG, fontWeight: 600 }}>{t}</div>
                  <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 10.5,
                                  color: DL_DIM, marginTop: 4 }}>{sub}</div>
                </div>
              ))}
            </div>
          </div>
        </DLReveal>

        {/* SQL Server */}
        <DLReveal dir="right" delay={120}>
          <div style={{
            position: 'relative',
            padding: 'clamp(28px, 3vw, 40px)',
            borderRadius: 18,
            border: `1px solid ${DL_LINE}`,
            background: `linear-gradient(180deg, ${DL_SURFACE} 0%, ${DL_BG} 100%)`,
            display: 'flex', flexDirection: 'column', gap: 24,
            overflow: 'hidden', minHeight: 360,
          }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
              <div style={{
                width: 56, height: 56, borderRadius: 14,
                background: `radial-gradient(circle at 30% 30%, ${DL_ACCENT}, ${DL_ACCENT}aa)`,
                boxShadow: `0 0 32px ${DL_ACCENT}55, inset 0 0 0 1px rgba(255,255,255,.15)`,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>
                {/* Database glyph */}
                <svg width="28" height="28" viewBox="0 0 24 24" fill="none" aria-hidden="true">
                  <ellipse cx="12" cy="6" rx="8" ry="3" stroke="#fff" strokeWidth="1.8" />
                  <path d="M4 6v6c0 1.66 3.58 3 8 3s8-1.34 8-3V6" stroke="#fff" strokeWidth="1.8" />
                  <path d="M4 12v6c0 1.66 3.58 3 8 3s8-1.34 8-3v-6" stroke="#fff" strokeWidth="1.8" />
                </svg>
              </div>
              <div>
                <DLEyebrow color={DL_ACCENT}>Scale</DLEyebrow>
                <div style={{ fontFamily: 'Libre Bodoni, serif', fontWeight: 500,
                                fontSize: 32, color: DL_FG, letterSpacing: '-.01em',
                                marginTop: 4, lineHeight: 1 }}>SQL Server</div>
              </div>
            </div>

            <DLBody size={15} opacity={.82}>
              Queried the production parcel data to measure how often a single delivery
              collected more than one comment, and how tightly those comments clustered
              in time. The behaviour I saw in UXCam scaled into thousands of parcels.
            </DLBody>

            {/* Faux table summary — no SQL, just shape of result */}
            <div style={{
              marginTop: 'auto',
              borderRadius: 12,
              border: `1px solid ${DL_LINE}`,
              background: '#0e0606',
              overflow: 'hidden',
            }}>
              <div style={{
                display: 'grid', gridTemplateColumns: '1fr 1fr 1fr',
                fontFamily: 'DM Sans, sans-serif', fontSize: 10,
                letterSpacing: '.18em', textTransform: 'uppercase',
                color: DL_DIM, fontWeight: 600,
                padding: '12px 16px',
                borderBottom: `1px solid ${DL_LINE}`,
              }}>
                <span>Parcel</span>
                <span style={{ textAlign: 'center' }}>Messages</span>
                <span style={{ textAlign: 'right' }}>Median gap</span>
              </div>
              {[
                ['#284', 5, '6 min'],
                ['#312', 7, '4 min'],
                ['#508', 3, '11 min'],
                ['#621', 6, '5 min'],
              ].map(([id, msgs, gap], i) => (
                <div key={id} style={{
                  display: 'grid', gridTemplateColumns: '1fr 1fr 1fr',
                  alignItems: 'center',
                  fontFamily: 'DM Sans, sans-serif', fontSize: 13,
                  color: DL_FG, padding: '10px 16px',
                  borderTop: i ? `1px solid ${DL_LINE}` : 'none',
                }}>
                  <span style={{ color: DL_MUTED, fontVariantNumeric: 'tabular-nums' }}>{id}</span>
                  {/* Cell with mini bar */}
                  <span style={{ display: 'flex', alignItems: 'center', gap: 8,
                                   justifyContent: 'center' }}>
                    <span style={{ width: msgs * 8, height: 4, borderRadius: 999,
                                     background: DL_ACCENT,
                                     boxShadow: `0 0 6px ${DL_ACCENT}66` }} />
                    <span style={{ fontVariantNumeric: 'tabular-nums', fontWeight: 600 }}>{msgs}</span>
                  </span>
                  <span style={{ textAlign: 'right', color: DL_MUTED,
                                   fontVariantNumeric: 'tabular-nums' }}>{gap}</span>
                </div>
              ))}
            </div>

            <div style={{ display: 'flex', gap: 24, paddingTop: 18,
                            borderTop: `1px solid ${DL_LINE}` }}>
              {[
                ['Aggregated queries', 'volume'],
                ['Time-window joins', 'temporal patterns'],
                ['Validated hypothesis', 'evidence-led'],
              ].map(([t, sub]) => (
                <div key={t}>
                  <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 12,
                                  color: DL_FG, fontWeight: 600 }}>{t}</div>
                  <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 10.5,
                                  color: DL_DIM, marginTop: 4 }}>{sub}</div>
                </div>
              ))}
            </div>
          </div>
        </DLReveal>
      </div>

      {/* Tie-in line under the two */}
      <DLReveal delay={220}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center',
                        gap: 14, marginTop: 40,
                        fontFamily: 'DM Sans, sans-serif', fontSize: 11,
                        letterSpacing: '.2em', textTransform: 'uppercase',
                        color: DL_MUTED, fontWeight: 600 }}>
          <span style={{ width: 32, height: 1, background: DL_LINE }} />
          <span>UXCam saw it — SQL Server measured it</span>
          <span style={{ width: 32, height: 1, background: DL_LINE }} />
        </div>
      </DLReveal>
    </div>
  </DLSection>
);

// ── Decisions / process ─────────────────────────────────────────────────────
const DLDecisions = () => {
  const items = [
    ['01', 'Promote contact to first-class', 'Two big icons — call and chat — directly under the parcel info. Make the option exist on the screen the courier is already on.'],
    ['02', 'Keep the comment, narrow its job', 'The comment field stays for notes to the next courier shift — clearly separated from the new conversation channel.'],
    ['03', 'Same UI for both sides', 'The customer-facing app and the courier app use the same chat surface. One mental model, no role-specific quirks.'],
    ['04', 'Inbox, with unread counts', 'A dedicated "Skrzynka" tab. Notifications + Korespondencja separated, parcel number front-and-centre.'],
    ['05', 'Anonymised identities', 'Names appear as placeholders. Parcel number, not personal data, is the conversation anchor.'],
  ];
  return (
    <DLSection bg={DL_SURFACE} style={{ borderTop: `1px solid ${DL_LINE}`, borderBottom: `1px solid ${DL_LINE}` }}>
      <div style={{ maxWidth: 1280 }}>
        <DLReveal>
          <DLEyebrow>Design decisions</DLEyebrow>
          <DLHeading size={'clamp(36px, 3.8vw, 56px)'} style={{ marginTop: 14, marginBottom: 56, maxWidth: 880 }}>
            Five calls, made on the evidence.
          </DLHeading>
        </DLReveal>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(280px, 1fr))', gap: 32 }}>
          {items.map(([n, title, desc], i) => (
            <DLReveal key={n} delay={i * 70}>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 12,
                              paddingTop: 24, borderTop: `1px solid ${DL_LINE}` }}>
                <span style={{ fontFamily: 'Libre Bodoni, serif', fontSize: 22, color: DL_ACCENT,
                                 fontWeight: 500, fontStyle: 'italic' }}>{n}</span>
                <div style={{ fontFamily: 'Libre Bodoni, serif', fontSize: 22, color: DL_FG,
                                fontWeight: 500, lineHeight: 1.15, letterSpacing: '-.01em' }}>{title}</div>
                <DLBody size={14.5} opacity={.7} maxWidth={320}>{desc}</DLBody>
              </div>
            </DLReveal>
          ))}
        </div>
      </div>
    </DLSection>
  );
};

// ── The redesign — walkthrough ──────────────────────────────────────────────
const DLPrototype = () => {
  const steps = [
    { src: 'case-assets/delivery/parcel-redesign.png', n: '01', t: 'Parcel — with contact',
      d: 'Two prominent icons under the address: call and chat. The comment field stays, demoted to a "note to next shift" role.' },
    { src: 'case-assets/delivery/inbox.png',          n: '02', t: 'Inbox · Correspondence',
      d: 'A dedicated tab. Correspondence and Notifications split. Each row is anchored by the parcel number — never a person.' },
    { src: 'case-assets/delivery/chat.png',           n: '03', t: 'Conversation',
      d: 'A standard messenger surface. The parcel number sits in the header so the user always knows which delivery they are discussing.' },
  ];
  return (
    <DLSection style={{ borderTop: `1px solid ${DL_LINE}` }}>
      <div style={{ maxWidth: 1280 }}>
        <DLReveal>
          <DLEyebrow>The prototype</DLEyebrow>
          <DLHeading size={'clamp(36px, 3.8vw, 56px)'} style={{ marginTop: 14, marginBottom: 16, maxWidth: 880 }}>
            From comment field to <span style={{ fontStyle: 'italic', color: DL_ACCENT }}>in-app chat.</span>
          </DLHeading>
          <DLBody size={17} opacity={.8} maxWidth={780} style={{ marginBottom: 56 }}>
            Four screens carry the new conversation channel — from the parcel screen the
            courier already lives on, through a proper inbox, into a chat that names the
            parcel rather than the person.
          </DLBody>
        </DLReveal>

        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 32, alignItems: 'start' }}>
          {steps.map((s, i) => (
            <DLReveal key={s.n} delay={i * 90}>
              <figure style={{ margin: 0, display: 'grid', gridTemplateRows: 'auto auto auto auto', gap: 12 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                  <span style={{ fontFamily: 'Libre Bodoni, serif', fontSize: 22, color: DL_ACCENT,
                                   fontWeight: 500, fontStyle: 'italic' }}>{s.n}</span>
                  <span style={{ flex: 1, height: 1, background: DL_LINE }} />
                </div>
                <DLPhone src={s.src} alt={s.t} width={210} scrollable />
                <figcaption style={{ fontFamily: 'Libre Bodoni, serif', fontSize: 22, color: DL_FG,
                                       fontWeight: 500, letterSpacing: '-.01em', lineHeight: 1.15, marginTop: 8 }}>{s.t}</figcaption>
                <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 13.5, color: DL_FG,
                                opacity: .65, lineHeight: 1.55 }}>{s.d}</div>
              </figure>
            </DLReveal>
          ))}
        </div>
      </div>
    </DLSection>
  );
};

const DLModes = () => (
  <DLSection style={{ borderTop: `1px solid ${DL_LINE}` }}>
    <div style={{ maxWidth: 1280 }}>
      <DLReveal>
        <DLEyebrow>Light & dark mode</DLEyebrow>
        <DLHeading size={'clamp(36px, 3.8vw, 56px)'} style={{ marginTop: 14, marginBottom: 18, maxWidth: 880 }}>
          Built for the <span style={{ fontStyle: 'italic', color: DL_ACCENT }}>doorstep</span>, not the desk.
        </DLHeading>
        <DLBody size={17} opacity={.8} maxWidth={780} style={{ marginBottom: 56 }}>
          Couriers work in glare, rain and dim stairwells — often one-handed. A full
          light and dark theme lets the app match the environment: dark mode saves
          battery and eyes at night, light mode stays legible in bright daylight.
          One toggle, every screen.
        </DLBody>
      </DLReveal>

      <DLReveal delay={120}>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr',
                       gap: 'clamp(32px, 5vw, 80px)', marginBottom: 48 }}>
          {[
            { label: 'Dark mode', sub: 'Night shifts, dim stairwells, battery saving.',
              shots: ['case-assets/delivery/anim-stats-dark.png', 'case-assets/delivery/anim-confirm-dark.png'] },
            { label: 'Light mode', sub: 'Bright daylight, glare, outdoor legibility.',
              shots: ['case-assets/delivery/stats-light.png', 'case-assets/delivery/anim-confirm-light.png'] },
          ].map((m, mi) => (
            <div key={m.label} style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>
              <div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                  <span style={{ width: 9, height: 9, borderRadius: '50%',
                                   background: mi === 0 ? '#1a1a1a' : '#fff',
                                   border: `1px solid ${DL_ACCENT}`,
                                   boxShadow: `0 0 10px ${DL_ACCENT}66` }} />
                  <div style={{ fontFamily: 'Libre Bodoni, serif', fontSize: 26,
                                  fontWeight: 500, color: DL_FG, letterSpacing: '-.01em' }}>{m.label}</div>
                </div>
                <DLBody size={13.5} opacity={.65} style={{ marginTop: 8 }}>{m.sub}</DLBody>
              </div>
              <div style={{ display: 'flex', gap: 18, justifyContent: 'center' }}>
                {m.shots.map((s, si) => (
                  <div key={s} style={{ transform: `rotate(${si ? 4 : -4}deg)` }}>
                    <DLPhone src={s} alt={`${m.label} screen`} width={188} />
                  </div>
                ))}
              </div>
            </div>
          ))}
        </div>
      </DLReveal>

      <DLReveal delay={200}>
        <div style={{
          padding: 'clamp(28px, 3vw, 40px)', borderRadius: 18,
          border: `1px solid ${DL_LINE}`,
          background: `linear-gradient(135deg, ${DL_ACCENT}10 0%, transparent 60%), ${DL_BG}`,
          display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 28,
        }}>
          {[
            ['Why both', 'A delivery app lives outdoors. No single theme works across a 10-hour shift that spans daylight and dark.'],
            ['Same contrast budget', 'Both themes hit the same legibility bar — status colours (red / green / amber) stay distinct in either mode.'],
            ['One tap, in Settings', 'The toggle sits in Settings — set once, persists. No per-screen decision, no hunting.'],
          ].map(([k, v]) => (
            <div key={k} style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
              <DLEyebrow color={DL_ACCENT}>{k}</DLEyebrow>
              <DLBody size={13.5} opacity={.78}>{v}</DLBody>
            </div>
          ))}
        </div>
      </DLReveal>
    </div>
  </DLSection>
);

// ── Outcome ─────────────────────────────────────────────────────────────────
const DLOutcome = () => {
  const stats = [
    ['1,400+', 'Comment-threads-as-chats', 'Detected in one month of October data — the volume that justified building real chat.'],
    ['2 → 1',  'Tools, then one',          'Couriers used to switch between the comment field and the support call. The chat collapses them.'],
    ['Shipped', 'Prototype validated',     'Validated with couriers and customer-side users. Greenlit for engineering.'],
  ];
  return (
    <DLSection bg={DL_SURFACE} style={{ borderTop: `1px solid ${DL_LINE}` }}>
      <div style={{ maxWidth: 1280 }}>
        <DLReveal>
          <DLEyebrow>Outcome</DLEyebrow>
          <DLHeading size={'clamp(36px, 3.8vw, 56px)'} style={{ marginTop: 14, marginBottom: 64, maxWidth: 760 }}>
            From hunch to <span style={{ fontStyle: 'italic', color: DL_ACCENT }}>roadmap.</span>
          </DLHeading>
        </DLReveal>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(260px, 1fr))', gap: 48 }}>
          {stats.map(([n, label, desc], i) => (
            <DLReveal key={label} delay={i * 110}>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 14,
                              paddingTop: 24, borderTop: `1px solid ${DL_LINE}` }}>
                <div style={{ fontFamily: 'Libre Bodoni, serif', fontWeight: 500,
                                fontSize: 'clamp(48px, 5.4vw, 78px)', lineHeight: 1, color: DL_ACCENT,
                                letterSpacing: '-.02em', textShadow: `0 0 32px ${DL_ACCENT}33` }}>{n}</div>
                <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 14, color: DL_FG,
                                letterSpacing: '.14em', textTransform: 'uppercase', fontWeight: 600 }}>{label}</div>
                <DLBody size={14.5} opacity={.7} maxWidth={300}>{desc}</DLBody>
              </div>
            </DLReveal>
          ))}
        </div>
      </div>
    </DLSection>
  );
};

// ── Modal shell ─────────────────────────────────────────────────────────────
const DeliveryCaseStudy = ({ open, onClose }) => {
  React.useEffect(() => {
    if (!open) return undefined;
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => { document.body.style.overflow = prev; };
  }, [open]);

  React.useEffect(() => {
    if (!open) return undefined;
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, onClose]);

  const scrollRef = React.useRef(null);
  const [progress, setProgress] = React.useState(0);
  const onScroll = (e) => {
    const el = e.currentTarget;
    const max = el.scrollHeight - el.clientHeight;
    setProgress(max > 0 ? el.scrollTop / max : 0);
  };
  React.useEffect(() => {
    if (open && scrollRef.current) { scrollRef.current.scrollTop = 0; setProgress(0); }
  }, [open]);

  return (
    <div aria-hidden={!open}
         style={{ position: 'fixed', inset: 0, zIndex: 100,
                   pointerEvents: open ? 'auto' : 'none' }}>
      <div onClick={onClose} style={{
        position: 'absolute', inset: 0, background: 'rgba(0,0,0,.55)',
        opacity: open ? 1 : 0, transition: 'opacity .5s ease',
        backdropFilter: 'blur(4px)', WebkitBackdropFilter: 'blur(4px)',
      }} />

      <div ref={scrollRef} onScroll={onScroll}
           style={{
             position: 'absolute', inset: 0,
             background: DL_BG, color: DL_FG,
             transform: open ? 'translateY(0)' : 'translateY(40px)',
             opacity: open ? 1 : 0,
             transition: 'transform .55s cubic-bezier(.5,0,.2,1), opacity .45s ease',
             overflowY: 'auto', overflowX: 'hidden',
             scrollbarColor: `${DL_ACCENT}66 transparent`,
           }}>
        <style>{`
          @keyframes dlMeshDrift {
            0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
            50%      { transform: translate3d(-20px, 12px, 0) scale(1.04); }
          }
          @keyframes dlVanRoll {
            0%, 100% { transform: translateX(0); }
            50%      { transform: translateX(6px); }
          }
          @keyframes dlPulse {
            0%, 100% { opacity: 1; transform: scale(1); }
            50%      { opacity: .4; transform: scale(1.4); }
          }
          .dl-mesh { animation: dlMeshDrift 14s ease-in-out infinite; }
        `}</style>

        <div style={{
          position: 'sticky', top: 0, zIndex: 50,
          background: `linear-gradient(${DL_BG} 70%, ${DL_BG}00)`,
          padding: '20px max(56px, 5vw)',
        }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <button onClick={onClose} style={{
              appearance: 'none', border: 'none', background: 'none', padding: 6,
              color: DL_FG, cursor: 'pointer',
              display: 'inline-flex', alignItems: 'center', gap: 12,
              fontFamily: 'DM Sans, sans-serif', fontSize: 12,
              letterSpacing: '.18em', textTransform: 'uppercase', fontWeight: 600,
            }}>
              <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
                <path d="M19 12H5M11 6l-6 6 6 6" stroke="currentColor" strokeWidth="1.6"
                      strokeLinecap="round" strokeLinejoin="round" />
              </svg>
              <span>Back to portfolio</span>
            </button>
            <div style={{ display: 'inline-flex', alignItems: 'center', gap: 18 }}>
              <DLEyebrow>Case 03 · UXCam Research</DLEyebrow>
              <button onClick={onClose} aria-label="Close" style={{
                appearance: 'none', border: 'none', background: 'none', cursor: 'pointer',
                color: DL_FG, padding: 6, display: 'inline-flex',
              }}>
                <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
                  <path d="M6 6l12 12M18 6L6 18" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
                </svg>
              </button>
            </div>
          </div>
          <div style={{ position: 'relative', height: 1.5, marginTop: 16,
                         background: DL_LINE, borderRadius: 999 }}>
            <div style={{ position: 'absolute', left: 0, top: 0, bottom: 0,
                             width: `${progress * 100}%`, background: DL_ACCENT,
                             borderRadius: 999, transition: 'width .1s linear' }} />
          </div>
        </div>

        <DLHero />
        <DLHypothesis />
        <DLBefore />
        <DLToolkit />
        <DLResearch />
        <DLDecisions />
        <DLPrototype />
        <DLModes />
        <DLOutcome />

        <DLSection py={72} style={{ borderTop: `1px solid ${DL_LINE}` }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                          flexWrap: 'wrap', gap: 32 }}>
            <div>
              <DLEyebrow>End of case · 03 / 04</DLEyebrow>
              <DLHeading size={32} style={{ marginTop: 8 }}>More work — coming soon.</DLHeading>
            </div>
            <button onClick={onClose} style={{
              appearance: 'none', border: `1px solid ${DL_LINE}`, background: 'transparent',
              color: DL_FG, padding: '18px 32px', borderRadius: 999, cursor: 'pointer',
              fontFamily: 'DM Sans, sans-serif', fontSize: 13,
              letterSpacing: '.18em', textTransform: 'uppercase', fontWeight: 600,
              display: 'inline-flex', alignItems: 'center', gap: 14,
            }}>
              <span>Back to portfolio</span>
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
                <path d="M19 12H5M11 6l-6 6 6 6" stroke="currentColor" strokeWidth="1.6"
                      strokeLinecap="round" strokeLinejoin="round" />
              </svg>
            </button>
          </div>
        </DLSection>
      </div>
    </div>
  );
};

Object.assign(window, { DeliveryCaseStudy });
