// Case study modal — Cashback Mobile App (plente-style cashback + shopping + giftcards).

const CB_ACCENT = '#FCC00D';
const CB_BG = '#1A1408';
const CB_SURFACE = '#241B0E';
const CB_FG = '#F8EFDA';
const CB_MUTED = 'rgba(248,239,218,.65)';
const CB_DIM = 'rgba(248,239,218,.42)';
const CB_LINE = 'rgba(248,239,218,.12)';

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

const CBHeading = ({ children, size = 48, weight = 500, color = CB_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 CBBody = ({ children, size = 16, color = CB_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 CBSection = ({ children, py = 96, bg, style }) => (
  <section style={{ padding: `${py}px max(56px, 5vw)`, background: bg, ...style }}>{children}</section>
);

// Reveal — IntersectionObserver fade-in (mirrors the helper in case-mvno.jsx).
const CBReveal = ({ 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>
  );
};

// Tiny iPhone-ish frame around a real screen.
// When scrollable=true, the screen scrolls vertically inside the bezel so a
// long capture can be inspected in full without distorting the phone aspect.
const CBPhone = ({ src, alt, width = 280, accent = CB_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`,
  }}>
    {/* Side button hints make the frame read as a real phone */}
    <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',
           }} />
      {/* Tiny scroll-affordance label, only when scrollable */}
      {scrollable && (
        <div style={{
          position: 'sticky', bottom: 6, left: 0, right: 0,
          margin: '0 auto', width: 'fit-content',
          background: 'rgba(0,0,0,.55)', color: '#fff',
          padding: '4px 10px', borderRadius: 999,
          fontFamily: 'DM Sans, sans-serif', fontSize: 9,
          letterSpacing: '.18em', textTransform: 'uppercase',
          fontWeight: 600, pointerEvents: 'none',
        }}>Scroll ↕</div>
      )}
    </div>
  </div>
);

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

    <div style={{ position: 'relative', display: 'flex', flexDirection: 'column', gap: 48 }}>
      <CBReveal delay={50}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
          <CBEyebrow color={CB_ACCENT}>Case · 02</CBEyebrow>
          <span style={{ width: 32, height: 1, background: CB_LINE }} />
          <CBEyebrow>Cashback · E-commerce · Giftcards</CBEyebrow>
        </div>
      </CBReveal>

      <CBReveal delay={120}>
        <CBHeading size={'clamp(64px, 8vw, 144px)'}>
          Cashback <span style={{ fontStyle: 'italic', color: CB_ACCENT }}>Mobile App</span>
        </CBHeading>
      </CBReveal>

      <CBReveal delay={220}>
        <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr',
                       gap: 'clamp(40px, 5vw, 80px)', maxWidth: 1080, alignItems: 'start' }}>
          <CBBody size={20} maxWidth={600}>
            One mobile product that unifies three separate web platforms — cashback,
            shopping and gift cards — under one brand. A full redesign and a new
            product identity built from scratch.
          </CBBody>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, auto)', gap: '16px 48px' }}>
            {[
              ['Role',  'UX/UI Designer'],
              ['Type',  'Mobile app · merger of 3 platforms'],
              ['Scope', 'UX research → Design System → Brand'],
            ].map(([k, v]) => (
              <div key={k} style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
                <CBEyebrow>{k}</CBEyebrow>
                <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 15, color: CB_FG }}>{v}</div>
              </div>
            ))}
          </div>
        </div>
      </CBReveal>

      {/* Triptych — three phones, slight tilt, "merging into one" feel */}
      <CBReveal delay={300}>
        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center',
                       gap: 'clamp(-30px, -3vw, -12px)', marginTop: 32,
                       position: 'relative' }}>
          <div style={{ transform: 'rotate(-6deg) translateY(20px)', zIndex: 1, opacity: .9 }}>
            <CBPhone src="case-assets/cashback/zalando.png" alt="Shop details — Zalando Lounge" width={210} />
          </div>
          <div style={{ transform: 'translateY(-10px)', zIndex: 3, position: 'relative' }}>
            <CBPhone src="case-assets/cashback/transactions.png" alt="Your cashback — transactions" width={250} />
          </div>
          <div style={{ transform: 'rotate(6deg) translateY(20px)', zIndex: 1, opacity: .9 }}>
            <CBPhone src="case-assets/cashback/cart.png" alt="Shopping cart" width={210} />
          </div>
        </div>
      </CBReveal>
    </div>
  </CBSection>
);

// ── The goal ────────────────────────────────────────────────────────────────
const CBGoal = () => (
  <CBSection style={{ borderTop: `1px solid ${CB_LINE}` }}>
    <div style={{ maxWidth: 1280, display: 'grid', gridTemplateColumns: '1fr 1.4fr',
                   gap: 'clamp(48px, 6vw, 120px)', alignItems: 'start' }}>
      <CBReveal dir="left">
        <CBEyebrow>The goal</CBEyebrow>
        <CBHeading size={'clamp(36px, 3.8vw, 56px)'} style={{ marginTop: 14 }}>
          One app for <span style={{ color: CB_ACCENT, fontStyle: 'italic' }}>three platforms.</span>
        </CBHeading>
      </CBReveal>
      <CBReveal dir="right" delay={120}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 22 }}>
          <CBBody size={18}>
            Three web platforms — a cashback service, a shopping aggregator and a giftcard
            marketplace — needed to live under one mobile roof. Each had its own audience,
            patterns, and visual debt. None of them was made for mobile-first behaviour.
          </CBBody>
          <CBBody size={18}>
            The product redesign was paired with brand-building work: a new logotype, voice,
            colour and motion language strong enough to carry across all three jobs and
            still feel inevitable on a 6-inch screen.
          </CBBody>

          {/* Three pill labels */}
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 12, marginTop: 14 }}>
            {[
              ['Cashback',  'Earn % back per shop'],
              ['Shopping',  'Aggregated partner offers'],
              ['Giftcards', 'Buy + pay with saved cashback'],
            ].map(([title, sub], i) => (
              <div key={title} style={{
                padding: '14px 20px', borderRadius: 14,
                border: `1px solid ${CB_LINE}`, background: 'rgba(0,0,0,.18)',
                display: 'flex', flexDirection: 'column', gap: 4, minWidth: 180,
              }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                  <span style={{ width: 7, height: 7, borderRadius: '50%', background: CB_ACCENT,
                                   boxShadow: `0 0 8px ${CB_ACCENT}` }} />
                  <div style={{ fontFamily: 'Libre Bodoni, serif', fontSize: 18,
                                  fontWeight: 500, color: CB_FG }}>{title}</div>
                </div>
                <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 12, color: CB_MUTED }}>{sub}</div>
              </div>
            ))}
          </div>
        </div>
      </CBReveal>
    </div>
  </CBSection>
);

// ── Responsibilities ────────────────────────────────────────────────────────
const CBResponsibilities = () => {
  const items = [
    ['01', 'User needs analysis', 'Mapped the three audiences and the overlap between cashback shoppers and giftcard buyers. Defined the unified user.'],
    ['02', 'Stakeholder interviews', 'Aligned product, marketing and ops on a single story for the merged platform — and what each side would not give up.'],
    ['03', 'Unified Design System', 'Tokens, typography, components, motion. The first source of truth shared across cashback, shopping and giftcards.'],
    ['04', 'Brand-into-product', 'Translated the new brand identity into mobile patterns — the yellow card, the bodoni headlines, the warm photography.'],
    ['05', 'New flows', 'Designed flows the web never had: address management, parcel locker pick-up, integrated checkout with cashback as a payment method.'],
    ['06', 'Manual testing', 'Hands-on QA across all three product types — cashback flows, shopping checkout and giftcard purchase. Bug triage with engineering before each release.'],
  ];
  return (
    <CBSection bg={CB_SURFACE} style={{ borderTop: `1px solid ${CB_LINE}`, borderBottom: `1px solid ${CB_LINE}` }}>
      <div style={{ maxWidth: 1280 }}>
        <CBReveal>
          <CBEyebrow>My role · responsibilities</CBEyebrow>
          <CBHeading size={'clamp(36px, 3.8vw, 56px)'} style={{ marginTop: 14, marginBottom: 56 }}>
            What I owned end-to-end.
          </CBHeading>
        </CBReveal>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(280px, 1fr))', gap: 32 }}>
          {items.map(([n, title, desc], i) => (
            <CBReveal key={n} delay={i * 70}>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 12,
                              paddingTop: 24, borderTop: `1px solid ${CB_LINE}` }}>
                <span style={{ fontFamily: 'Libre Bodoni, serif', fontSize: 22, color: CB_ACCENT,
                                 fontWeight: 500, fontStyle: 'italic' }}>{n}</span>
                <div style={{ fontFamily: 'Libre Bodoni, serif', fontSize: 22, color: CB_FG,
                                fontWeight: 500, lineHeight: 1.15, letterSpacing: '-.01em' }}>{title}</div>
                <CBBody size={14.5} opacity={.7} maxWidth={320}>{desc}</CBBody>
              </div>
            </CBReveal>
          ))}
        </div>
      </div>
    </CBSection>
  );
};

// ── Brand-into-product ──────────────────────────────────────────────────────
const CBBrand = () => (
  <CBSection style={{ borderTop: `1px solid ${CB_LINE}` }}>
    <div style={{ maxWidth: 1280 }}>
      <CBReveal>
        <CBEyebrow>Brand into product</CBEyebrow>
        <CBHeading size={'clamp(36px, 3.8vw, 56px)'} style={{ marginTop: 14, marginBottom: 48, maxWidth: 760 }}>
          A loud yellow, a quiet system. <span style={{ fontStyle: 'italic', color: CB_ACCENT }}>Both on purpose.</span>
        </CBHeading>
      </CBReveal>

      <div style={{ display: 'grid', gridTemplateColumns: '1.1fr 1fr', gap: 48, alignItems: 'center' }}>
        <CBReveal dir="left">
          <div style={{ display: 'flex', flexDirection: 'column', gap: 26 }}>
            {[
              ['Marketing surface', 'The Twój cashback card is the brand object — strong yellow gradient, bodoni headline, big numbers. It anchors the dashboard, the profile and every checkout.'],
              ['One typeface family', 'Libre Bodoni for moments of voice (greetings, balances, headlines), DM Sans for everything functional. The shift in tone is the brand.'],
              ['Quiet UI, loud brand', 'Inputs, lists and form fields stay neutral. The yellow shows up only where it should reward attention — the primary CTA, the cashback total, the active state.'],
            ].map(([t, d]) => (
              <div key={t} style={{ display: 'flex', gap: 18, alignItems: 'flex-start' }}>
                <span style={{ width: 6, height: 6, borderRadius: '50%', background: CB_ACCENT,
                                 marginTop: 9, flexShrink: 0, boxShadow: `0 0 8px ${CB_ACCENT}` }} />
                <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                  <div style={{ fontFamily: 'Libre Bodoni, serif', fontSize: 22, fontWeight: 500,
                                  color: CB_FG, letterSpacing: '-.01em' }}>{t}</div>
                  <CBBody size={14.5} opacity={.75} maxWidth={460}>{d}</CBBody>
                </div>
              </div>
            ))}
          </div>
        </CBReveal>

        <CBReveal dir="right" delay={150}>
          <div style={{ display: 'flex', gap: 18, justifyContent: 'center', alignItems: 'flex-end' }}>
            <div style={{ transform: 'rotate(-4deg) translateY(10px)' }}>
              <CBPhone src="case-assets/cashback/summary-priv.png" alt="Checkout summary — yellow CTA" width={220} />
            </div>
            <div style={{ transform: 'rotate(4deg)' }}>
              <CBPhone src="case-assets/cashback/levels.png" alt="Cashback levels — Bronze/Silver/Gold/Diamond" width={220} />
            </div>
          </div>
        </CBReveal>
      </div>
    </div>
  </CBSection>
);

// ── NEW FLOW: Address management ────────────────────────────────────────────
// Walks through the design thinking behind a flow the web product never had.
const CBAddressFlow = () => {
  const steps = [
    { src: 'case-assets/cashback/addr-empty.png',  n: '01', t: 'Empty state',          d: 'Single screen, no fluff. CTA disabled until required fields validate — the user knows what is left to fill.' },
    { src: 'case-assets/cashback/addr-filled.png', n: '02', t: 'Inline validation',    d: 'Field-by-field, no submit-then-yell. The CTA flips to the brand yellow only when the data is good to go.' },
    { src: 'case-assets/cashback/addr-france.png', n: '03', t: 'Country-aware fields', d: 'Selecting a non-PL country invalidates dependent fields. Same screen, but the user sees what changed without losing their place.' },
    { src: 'case-assets/cashback/addr-list.png',   n: '04', t: 'Saved addresses',      d: 'Once saved, the address becomes reusable. A single preferred-delivery toggle removes the next checkout decision before it appears.' },
  ];
  return (
    <CBSection bg={CB_SURFACE} style={{ borderTop: `1px solid ${CB_LINE}`, borderBottom: `1px solid ${CB_LINE}` }}>
      <div style={{ maxWidth: 1280 }}>
        <CBReveal>
          <CBEyebrow>New flow · not in web</CBEyebrow>
          <CBHeading size={'clamp(36px, 3.8vw, 56px)'} style={{ marginTop: 14, marginBottom: 16, maxWidth: 880 }}>
            Address management — designing a flow the web <span style={{ fontStyle: 'italic', color: CB_ACCENT }}>never had.</span>
          </CBHeading>
          <CBBody size={17} opacity={.8} maxWidth={780} style={{ marginBottom: 56 }}>
            The web product didn't store delivery addresses — every purchase re-asked for them.
            On mobile that breaks the "buy in two taps" promise. I designed the missing layer:
            add, edit, switch and pick the preferred delivery address — directly inside checkout
            or from the profile.
          </CBBody>
        </CBReveal>

        {/* 4-step walkthrough */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 32, alignItems: 'start' }}>
          {steps.map((s, i) => (
            <CBReveal 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: CB_ACCENT,
                                   fontWeight: 500, fontStyle: 'italic' }}>{s.n}</span>
                  <span style={{ flex: 1, height: 1, background: CB_LINE }} />
                </div>
                <CBPhone src={s.src} alt={s.t} width={210} scrollable />
                <figcaption style={{ fontFamily: 'Libre Bodoni, serif', fontSize: 22, color: CB_FG,
                                       fontWeight: 500, letterSpacing: '-.01em', lineHeight: 1.15, marginTop: 8 }}>{s.t}</figcaption>
                <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 13.5, color: CB_FG,
                                opacity: .65, lineHeight: 1.55 }}>{s.d}</div>
              </figure>
            </CBReveal>
          ))}
        </div>

        {/* Decision rationale strip */}
        <CBReveal delay={220}>
          <div style={{
            marginTop: 64,
            padding: 'clamp(28px, 3vw, 40px)',
            borderRadius: 18,
            border: `1px solid ${CB_LINE}`,
            background: `linear-gradient(135deg, ${CB_ACCENT}10 0%, transparent 60%), ${CB_BG}`,
            display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 28,
          }}>
            {[
              ['Why one screen', 'Splitting the form into steps would have added taps and a back-stack the user has to debug. One scrollable card kept the mental model flat.'],
              ['Why nickname-first', '"Home" / "Office" labels reduce cognitive load at checkout — users pick by intent, not by re-reading street names.'],
              ['Why preferred toggle', 'A single radio in the list removes a recurring decision at checkout. Cashback users buy small things often; every saved tap compounds.'],
              ['Why inline edits', 'Editing a saved address from the checkout screen keeps the user in the buying mindset — no profile detour, no lost cart.'],
            ].map(([k, v]) => (
              <div key={k} style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                <CBEyebrow color={CB_ACCENT}>{k}</CBEyebrow>
                <CBBody size={13.5} opacity={.78}>{v}</CBBody>
              </div>
            ))}
          </div>
        </CBReveal>
      </div>
    </CBSection>
  );
};

// ── Checkout merge — three roads into one ───────────────────────────────────
const CBCheckout = () => {
  const flow = [
    { src: 'case-assets/cashback/cart.png',         label: 'Cart',                  sub: 'A toggle in the cart switches between Products and Giftcards — both live side by side, shortening the order process.' },
    { src: 'case-assets/cashback/summary-gc.png',   label: 'Order summary',         sub: 'Digital delivery, no shipping. Pay with saved cashback as a method.' },
    { src: 'case-assets/cashback/summary-1.png',    label: 'Address-aware summary', sub: 'Picking a parcel locker on the first order also saves the phone number — the user never re-types it on the next purchase.' },
    { src: 'case-assets/cashback/paczkomat.png',    label: 'Parcel locker',         sub: 'Map-based locker picker replaces a clunky 3-step web wizard.' },
  ];
  return (
    <CBSection style={{ borderTop: `1px solid ${CB_LINE}` }}>
      <div style={{ maxWidth: 1280 }}>
        <CBReveal>
          <CBEyebrow>Checkout</CBEyebrow>
          <CBHeading size={'clamp(36px, 3.8vw, 56px)'} style={{ marginTop: 14, marginBottom: 16, maxWidth: 880 }}>
            One checkout. <span style={{ fontStyle: 'italic', color: CB_ACCENT }}>Three product types.</span>
          </CBHeading>
          <CBBody size={17} opacity={.8} maxWidth={780} style={{ marginBottom: 56 }}>
            Giftcards, products and cashback payouts all settle in the same summary screen.
            The summary adapts: physical items get a delivery card, digital ones don't, and
            saved cashback always shows up as an opt-in payment method.
          </CBBody>
        </CBReveal>

        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 32, alignItems: 'start' }}>
          {flow.map((s, i) => (
            <CBReveal key={i} delay={i * 90}>
              <figure style={{ margin: 0, display: 'grid', gridTemplateRows: 'auto auto auto', gap: 12 }}>
                <CBPhone src={s.src} alt={s.label} width={210} />
                <figcaption style={{ fontFamily: 'Libre Bodoni, serif', fontSize: 22, color: CB_FG,
                                       fontWeight: 500, lineHeight: 1.1, marginTop: 8 }}>{s.label}</figcaption>
                <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 13.5, color: CB_FG,
                                opacity: .6, lineHeight: 1.55 }}>{s.sub}</div>
              </figure>
            </CBReveal>
          ))}
        </div>
      </div>
    </CBSection>
  );
};

// ── Design system + Marketing surface ───────────────────────────────────────
const CBSystem = () => (
  <CBSection bg={CB_SURFACE} style={{ borderTop: `1px solid ${CB_LINE}` }}>
    <div style={{ maxWidth: 1280 }}>
      <CBReveal>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
                       gap: 48, marginBottom: 48, flexWrap: 'wrap' }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14, maxWidth: 520 }}>
            <CBEyebrow>Design system · marketing</CBEyebrow>
            <CBHeading size={'clamp(32px, 3.4vw, 48px)'}>
              Components, motion, <span style={{ fontStyle: 'italic', color: CB_ACCENT }}>brand.</span>
            </CBHeading>
          </div>
          <CBBody size={15} opacity={.7} maxWidth={420}>
            A single system carries cashback, shop and giftcards — and the marketing site
            that drives traffic into the app. Same tokens, same patterns.
          </CBBody>
        </div>
      </CBReveal>

      <CBReveal delay={120}>
        <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 32, alignItems: 'stretch' }}>
          {/* Big composite card */}
          <div style={{
            borderRadius: 18, padding: 'clamp(32px, 3vw, 48px)',
            border: `1px solid ${CB_LINE}`, background: CB_BG,
            display: 'flex', flexDirection: 'column', gap: 32,
          }}>
            {/* Color swatches */}
            <div>
              <CBEyebrow>Palette</CBEyebrow>
              <div style={{ display: 'flex', gap: 12, marginTop: 14 }}>
                {[
                  ['#FCC00D', 'Brand · Yellow'],
                  ['#1A1408', 'Surface · Deep'],
                  ['#F8EFDA', 'Cream'],
                  ['#222', 'Ink'],
                  ['#FF914D', 'Accent · Warm'],
                ].map(([c, label]) => (
                  <div key={c} style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 8 }}>
                    <div style={{
                      height: 72, borderRadius: 10, background: c,
                      boxShadow: c === CB_BG ? `inset 0 0 0 1px ${CB_LINE}` : 'none',
                    }} />
                    <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 10,
                                    letterSpacing: '.14em', textTransform: 'uppercase',
                                    color: CB_MUTED, fontWeight: 600 }}>{label}</div>
                  </div>
                ))}
              </div>
            </div>

            {/* Type pair */}
            <div>
              <CBEyebrow>Typography</CBEyebrow>
              <div style={{ marginTop: 18, display: 'flex', flexDirection: 'column', gap: 16 }}>
                <div>
                  <div style={{ fontFamily: 'Libre Bodoni, serif', fontSize: 56, color: CB_FG,
                                  lineHeight: 1, letterSpacing: '-.02em', fontWeight: 500 }}>
                    Twój <span style={{ fontStyle: 'italic', color: CB_ACCENT }}>cashback</span>
                  </div>
                  <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 10,
                                  letterSpacing: '.18em', textTransform: 'uppercase',
                                  color: CB_DIM, fontWeight: 600, marginTop: 6 }}>
                    Libre Bodoni · headlines + numbers
                  </div>
                </div>
                <div>
                  <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 16, color: CB_FG, opacity: .85 }}>
                    Every flow rests on DM Sans for clarity, and lifts into Bodoni at the
                    brand-defining moments. The contrast is the system.
                  </div>
                  <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 10,
                                  letterSpacing: '.18em', textTransform: 'uppercase',
                                  color: CB_DIM, fontWeight: 600, marginTop: 6 }}>
                    DM Sans · body + labels
                  </div>
                </div>
              </div>
            </div>

            {/* Buttons */}
            <div>
              <CBEyebrow>Buttons</CBEyebrow>
              <div style={{ display: 'flex', gap: 14, marginTop: 14, flexWrap: 'wrap' }}>
                <div style={{ padding: '14px 28px', borderRadius: 999, background: CB_ACCENT,
                                color: '#1a1a1a', fontFamily: 'DM Sans, sans-serif', fontSize: 14,
                                fontWeight: 600 }}>Kupuję i płacę</div>
                <div style={{ padding: '14px 28px', borderRadius: 999, background: 'rgba(255,255,255,.05)',
                                color: CB_FG, fontFamily: 'DM Sans, sans-serif', fontSize: 14,
                                fontWeight: 500, border: `1px solid ${CB_LINE}` }}>Wybierz paczkomat</div>
                <div style={{ padding: '14px 28px', borderRadius: 999, background: 'transparent',
                                color: CB_ACCENT, fontFamily: 'DM Sans, sans-serif', fontSize: 14,
                                fontWeight: 600, border: `1px solid ${CB_ACCENT}55` }}>Dodaj kolejny adres</div>
              </div>
            </div>
          </div>

          {/* Brand object — Cashback card preview */}
          <div style={{
            borderRadius: 18, padding: 'clamp(28px, 3vw, 40px)',
            border: `1px solid ${CB_LINE}`,
            background: `linear-gradient(135deg, ${CB_ACCENT}10 0%, transparent 60%), ${CB_BG}`,
            display: 'flex', flexDirection: 'column', gap: 22, justifyContent: 'space-between',
          }}>
            <div>
              <CBEyebrow color={CB_ACCENT}>Brand object</CBEyebrow>
              <CBHeading size={28} style={{ marginTop: 10 }}>The yellow card.</CBHeading>
              <CBBody size={13.5} opacity={.7} style={{ marginTop: 12, maxWidth: 360 }}>
                A single recognisable object the user sees in every flow — profile,
                transactions, checkout. It's the logotype's job, done by UI.
              </CBBody>
            </div>
            {/* Mini cashback card */}
            <div style={{
              borderRadius: 14, padding: '22px 22px 0',
              background: 'linear-gradient(135deg, #FCC00D 0%, #F2AC1F 100%)',
              color: '#1a1a1a', fontFamily: 'DM Sans, sans-serif',
              boxShadow: '0 20px 40px -10px rgba(252,192,13,.3)',
            }}>
              <div style={{ fontFamily: 'Libre Bodoni, serif', fontSize: 22,
                              fontWeight: 600, textAlign: 'center', marginBottom: 14 }}>Twój cashback</div>
              <div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '4px 16px',
                              fontSize: 13, marginBottom: 16 }}>
                <span style={{ fontWeight: 700 }}>1202,00</span><span>Uznany</span>
                <span style={{ fontWeight: 700 }}>920,40</span><span>Oczekiwany</span>
                <span style={{ fontWeight: 700 }}>2122,40</span><span>Suma oszczędności</span>
              </div>
              <div style={{ background: '#1a1a1a', color: CB_ACCENT, fontWeight: 600,
                              fontSize: 11, padding: '10px 14px',
                              marginLeft: -22, marginRight: -22, marginBottom: 0,
                              borderBottomLeftRadius: 14, borderBottomRightRadius: 14 }}>
                Jak działa cashback?
              </div>
            </div>
          </div>
        </div>
      </CBReveal>
    </div>
  </CBSection>
);

// ── Impact ──────────────────────────────────────────────────────────────────
const CBImpact = () => {
  const stats = [
    ['−30%',   'QA-reported UI issues', 'A single Design System cleared the inconsistencies that had piled up across three legacy stacks.'],
    ['1 → 3',  'Platforms merged',      'Cashback, shopping and giftcards behind one product and one brand — the first time mobile-first.'],
    ['Lower',  'Checkout friction',     'A unified summary, saved addresses and parcel locker picker cut taps and decisions in the buying flow.'],
  ];
  return (
    <CBSection style={{ borderTop: `1px solid ${CB_LINE}` }}>
      <div style={{ maxWidth: 1280 }}>
        <CBReveal>
          <CBEyebrow>Impact</CBEyebrow>
          <CBHeading size={'clamp(36px, 3.8vw, 56px)'} style={{ marginTop: 14, marginBottom: 64, maxWidth: 760 }}>
            Three platforms, <span style={{ fontStyle: 'italic', color: CB_ACCENT }}>one experience.</span>
          </CBHeading>
        </CBReveal>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(260px, 1fr))', gap: 48 }}>
          {stats.map(([n, label, desc], i) => (
            <CBReveal key={label} delay={i * 110}>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 14,
                              paddingTop: 24, borderTop: `1px solid ${CB_LINE}` }}>
                <div style={{ fontFamily: 'Libre Bodoni, serif', fontWeight: 500,
                                fontSize: 'clamp(56px, 6vw, 88px)', lineHeight: 1, color: CB_ACCENT,
                                letterSpacing: '-.02em', textShadow: `0 0 32px ${CB_ACCENT}33` }}>{n}</div>
                <div style={{ fontFamily: 'DM Sans, sans-serif', fontSize: 14, color: CB_FG,
                                letterSpacing: '.14em', textTransform: 'uppercase', fontWeight: 600 }}>{label}</div>
                <CBBody size={14.5} opacity={.7} maxWidth={300}>{desc}</CBBody>
              </div>
            </CBReveal>
          ))}
        </div>
      </div>
    </CBSection>
  );
};

// ── Modal shell ─────────────────────────────────────────────────────────────
const CashbackCaseStudy = ({ 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: CB_BG, color: CB_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: `${CB_ACCENT}66 transparent`,
           }}>
        <style>{`
          @keyframes cbMeshDrift {
            0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
            50%      { transform: translate3d(-20px, 12px, 0) scale(1.04); }
          }
          .cb-mesh { animation: cbMeshDrift 14s ease-in-out infinite; }
        `}</style>

        {/* Top bar */}
        <div style={{
          position: 'sticky', top: 0, zIndex: 50,
          background: `linear-gradient(${CB_BG} 70%, ${CB_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: CB_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 }}>
              <CBEyebrow>Case 02 · Cashback</CBEyebrow>
              <button onClick={onClose} aria-label="Close" style={{
                appearance: 'none', border: 'none', background: 'none', cursor: 'pointer',
                color: CB_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: CB_LINE, borderRadius: 999 }}>
            <div style={{ position: 'absolute', left: 0, top: 0, bottom: 0,
                             width: `${progress * 100}%`, background: CB_ACCENT,
                             borderRadius: 999, transition: 'width .1s linear' }} />
          </div>
        </div>

        <CBHero />
        <CBGoal />
        <CBResponsibilities />
        <CBBrand />
        <CBAddressFlow />
        <CBCheckout />
        <CBSystem />
        <CBImpact />

        <CBSection py={72} style={{ borderTop: `1px solid ${CB_LINE}` }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                          flexWrap: 'wrap', gap: 32 }}>
            <div>
              <CBEyebrow>End of case · 02 / 04</CBEyebrow>
              <CBHeading size={32} style={{ marginTop: 8 }}>More work — coming soon.</CBHeading>
            </div>
            <button onClick={onClose} style={{
              appearance: 'none', border: `1px solid ${CB_LINE}`, background: 'transparent',
              color: CB_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>
        </CBSection>
      </div>
    </div>
  );
};

Object.assign(window, { CashbackCaseStudy });
