/* HOME — landing page composed of editorial sections. */

function HomePage() {
  return (
    <div data-screen-label="01 Home">
      <Hero />
      <Marquee />
      <FeatureGrid />
      <BeforeAfter />
      <BatchScale />
      <VideoGen />
      <SolutionsTeaser />
      <HomeGalleryStrip />
      <PricingTeaser />
      <CTABand />
    </div>);

}

window.HomePage = HomePage;

/* ---------------- Hero ----------------
   Full-bleed background image. Text sits over the negative space of the photo
   (the wall on the left, the floor along the bottom). No gradient overlay; the
   colours are locked so dark mode keeps the same light-hero treatment. */
function Hero() {
  const { isMobile } = useBreakpoint();

  // Locked colours — do NOT use var() tokens, so dark mode keeps the light treatment.
  const INK = '#0A0A0A';
  const GRAPHITE = '#4A4A4A';
  const FALLBACK_CREAM = '#F5EBDC'; // shown until the image paints

  return (
    <section style={{
      position: 'relative',
      background: FALLBACK_CREAM,
      overflow: 'hidden',
      minHeight: isMobile ? '82vh' : '88vh'
    }}>
      <img
        src="assets/hero-dog-campaign.jpg"
        alt=""
        aria-hidden="true"
        style={{
          position: 'absolute', inset: 0,
          width: '100%', height: '100%',
          objectFit: 'cover',
          objectPosition: isMobile ? '87% center' : 'right center',
          display: 'block'
        }} />

      {/* Foreground text sits over the wall (top-left) and the floor (bottom-left).
                                                         Aligned to the left edge of the container so it lands clear of the model + dogs. */}
      <div style={{
        position: 'relative', zIndex: 1,
        paddingLeft: 'var(--pad-x)', paddingRight: 'var(--pad-x)',
        minHeight: 'inherit'
      }}>
      <div style={{
        maxWidth: 'var(--container)', margin: '0 auto', width: '100%',
        paddingTop: 'clamp(48px, 8vw, 96px)',
        paddingBottom: isMobile ? '0px' : 'clamp(48px, 8vw, 96px)',
        display: 'grid',
        gridTemplateColumns: isMobile ? '1fr' : 'min(45vw, 640px) 1fr',
        alignItems: isMobile ? 'stretch' : 'center',
        minHeight: 'inherit'
      }}>
        <div style={isMobile ?
        { display: 'flex', flexDirection: 'column', justifyContent: 'space-between', height: '100%', paddingTop: 'clamp(4px, 2vw, 24px)', paddingBottom: 'clamp(6px, 2vw, 12px)' } :
        {}}>
          <div>
          <h1 style={{
              fontFamily: 'var(--font-display)', fontWeight: 400,
              fontSize: 'clamp(34px, 7.6vw, 120px)',
              lineHeight: 1.0, letterSpacing: '-0.04em',
              color: '#FFFFFF', textShadow: '0 2px 28px rgba(0,0,0,0.28)', margin: 0, maxWidth: '16ch'
            }}>
            <span style={{ whiteSpace: 'nowrap' }}>Studio-quality</span><br />
            <em style={{ fontStyle: 'italic', whiteSpace: 'nowrap', fontWeight: "400" }}>fashion images.</em>
          </h1>
          <p style={{
              marginTop: 'clamp(20px, 3vw, 28px)',
              lineHeight: 1.6,
              color: '#FFFFFF', maxWidth: isMobile ? '20ch' : '46ch',
              textShadow: '0 1px 3px rgba(0,0,0,0.35)', fontWeight: "700", fontSize: "18px"
            }}>
            Generate 4K imagery on real models from a single flat-lay. Direct the pose, the light, and the set. Skip the reshoot.
          </p>
          </div>
          <div style={{
            marginTop: isMobile ? 0 : 'clamp(24px, 4vw, 40px)',
            display: 'flex', flexDirection: isMobile ? 'column' : 'row',
            gap: 12, alignItems: isMobile ? 'stretch' : 'center',
            flexWrap: 'wrap'
          }}>
            <Button variant="primary" size="large" arrow onClick={() => {window.location.href = 'https://app.vizostudio.ai';}}>Start free trial</Button>
            <Link to="/contact"><Button variant="ghost" size="large" style={{ color: '#FFFFFF', textShadow: '0 1px 3px rgba(0,0,0,0.35)' }}>Contact us</Button></Link>
          </div>
        </div>
        {!isMobile && <div />}
      </div>
      </div>
    </section>);

}

/* ---------------- Marquee ---------------- */
function Marquee() {
  const words = ['E-commerce', 'Campaigns', 'Lookbooks', 'Social', 'Wholesale', 'Marketplace', 'Editorial', 'Bulk SKUs', 'Digital twin', 'Brand kit'];
  return (
    <section style={{ background: 'var(--ink)', color: 'var(--canvas)', overflow: 'hidden', borderTop: '1px solid var(--ink-soft)', borderBottom: '1px solid var(--ink-soft)', height: 'clamp(64px, 8vw, 96px)', display: 'flex', alignItems: 'center' }}>
      <div style={{ display: 'flex', whiteSpace: 'nowrap', animation: 'marq 40s linear infinite' }}>
        {[0, 1].map((loop) =>
        <div key={loop} style={{ display: 'flex', alignItems: 'center', gap: 'clamp(28px, 4vw, 48px)', flex: '0 0 auto', paddingRight: 'clamp(28px, 4vw, 48px)' }}>
            {words.map((w, i) =>
          <React.Fragment key={i}>
                <span style={{ fontFamily: 'var(--font-display)', fontSize: 'clamp(22px, 3.4vw, 36px)', fontWeight: 300, letterSpacing: '-0.02em' }}>{w}</span>
                <span style={{ fontFamily: 'var(--font-display)', color: 'var(--accent-amber)', fontSize: 'clamp(16px, 2.2vw, 24px)' }}>—</span>
              </React.Fragment>
          )}
          </div>
        )}
      </div>
      <style>{`@keyframes marq { from { transform: translateX(0); } to { transform: translateX(-50%); } }
        @media (prefers-reduced-motion: reduce) { @keyframes marq { from { transform: translateX(0); } to { transform: translateX(0); } } }`}</style>
    </section>);

}

/* ---------------- Feature grid ---------------- */
function FeatureGrid() {
  const { isMobile, isTablet } = useBreakpoint();
  const features = [
  { icon: 'camera', title: 'Your models & styling.',
    body: 'Pick the model, the pose, the light, the location. Your garment stays pixel-true to the original sample.' },
  { icon: 'layers', title: 'Variations in one click.',
    body: 'Generate a full size run, a colourway, or a campaign in a single batch. Tag, organise, and export by SKU.' },
  { icon: 'clapper', title: "Direct, don't retouch.",
    body: 'Move the model, change the season, swap the backdrop. No reshoot, no retoucher, no agency timeline.' }];

  return (
    <section style={{ padding: 'var(--pad-y) var(--pad-x)', background: 'var(--canvas)' }}>
      <div style={{ maxWidth: 'var(--container)', margin: '0 auto' }}>
        <Eyebrow>Platform</Eyebrow>
        <h2 style={{
          fontFamily: 'var(--font-display)', fontWeight: 400,
          fontSize: 'clamp(34px, 5.8vw, 56px)', lineHeight: 1.05, letterSpacing: '-0.03em',
          color: 'var(--ink)', margin: '20px 0 0', maxWidth: '16ch'
        }}>
          From idea to images in <em style={{ fontStyle: 'italic', fontWeight: 700 }}>minutes.</em>
        </h2>
        <div style={{
          marginTop: 'clamp(40px, 6vw, 72px)', display: 'grid',
          gridTemplateColumns: isMobile ? '1fr' : 'repeat(3, 1fr)',
          gap: 'clamp(28px, 4vw, 48px)'
        }}>
          {features.map((f) => {
            const IconComp = Icon[f.icon];
            return (
              <div key={f.title} style={{ paddingTop: 32, borderTop: '1px solid var(--bone)' }}>
                <IconComp width="28" height="28" style={{ color: 'var(--ink)' }} />
                <h3 style={{
                  fontFamily: 'var(--font-sans)', fontSize: 'clamp(20px, 2vw, 24px)', lineHeight: 1.3,
                  fontWeight: 600, letterSpacing: '-0.01em', color: 'var(--ink)',
                  margin: '24px 0 12px', maxWidth: '20ch'
                }}>{f.title}</h3>
                <p style={{ fontSize: 'clamp(16px, 1.1vw, 18px)', lineHeight: 1.65, color: 'var(--graphite)', margin: 0, maxWidth: '32ch' }}>
                  {f.body}
                </p>
              </div>);

          })}
        </div>
      </div>
    </section>);

}

/* ---------------- Before / After ---------------- */
function BeforeAfter() {
  const { isMobile } = useBreakpoint();
  const [t, setT] = React.useState(0.5);
  const wrap = React.useRef(null);
  const drag = React.useRef(false);
  const move = (clientX) => {
    if (!wrap.current) return;
    const r = wrap.current.getBoundingClientRect();
    const x = Math.min(1, Math.max(0, (clientX - r.left) / r.width));
    setT(x);
  };
  return (
    <section style={{ background: 'var(--paper)', padding: 'var(--pad-y) var(--pad-x)' }}>
      <div style={{ maxWidth: 'var(--container)', margin: '0 auto', display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '0.85fr 1fr', gap: 'clamp(28px, 5vw, 72px)', alignItems: 'center' }}>
        <div>
          <Eyebrow>Platform · 1.1</Eyebrow>
          <h2 style={{ fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 'clamp(34px, 5.8vw, 56px)', lineHeight: 1.05, letterSpacing: '-0.03em', color: 'var(--ink)', margin: '20px 0 0', maxWidth: '18ch' }}>
            From product to<br />campaign.<br /><em style={{ fontStyle: 'italic', fontWeight: 700 }}>Instantly.</em>
          </h2>
          <p style={{ marginTop: 24, fontSize: 'clamp(15px, 1.5vw, 17px)', lineHeight: 1.6, color: 'var(--graphite)', maxWidth: '40ch' }}>Either a ghost mannequin, flat-lay or an on model shot drives a complete set: model, pose, light, location. The garment stays pixel-true; the rest is direction.

          </p>
          <div style={{ marginTop: 28, display: 'flex', flexDirection: 'column', gap: 12, fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--slate)', letterSpacing: '0.04em', textTransform: 'uppercase' }}>
            <span>— Drag the divider</span>
          </div>
        </div>
        <div ref={wrap} style={{ position: 'relative', userSelect: 'none', cursor: 'col-resize', aspectRatio: '4 / 5', overflow: 'hidden' }}
        onMouseDown={(e) => {drag.current = true;move(e.clientX);}}
        onMouseMove={(e) => {if (drag.current) move(e.clientX);}}
        onMouseUp={() => {drag.current = false;}}
        onMouseLeave={() => {drag.current = false;}}
        onTouchStart={(e) => move(e.touches[0].clientX)}
        onTouchMove={(e) => move(e.touches[0].clientX)}>
          <FashionPlate ratio="4 / 5" label="Before · flat-lay" subject="" src="assets/before-orange-dress.png" fit="contain" position="10% center" bg="var(--paper)" idx={0} />
          <div style={{ position: 'absolute', inset: 0, clipPath: `inset(0 0 0 ${t * 100}%)` }}>
            <FashionPlate ratio="4 / 5" label="" subject="After · campaign" src="assets/after-orange-sky.jpg" position="center 20%" idx={2} />
          </div>
          {/* divider */}
          <div style={{ position: 'absolute', top: 0, bottom: 0, left: `${t * 100}%`, width: 2, background: 'var(--canvas)', boxShadow: '0 0 0 1px rgba(0,0,0,0.3)' }} />
          <div style={{ position: 'absolute', top: `calc(50% - 18px)`, left: `calc(${t * 100}% - 18px)`, width: 36, height: 36, borderRadius: 999, background: 'var(--canvas)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--ink)', boxShadow: '0 4px 14px rgba(0,0,0,0.18)' }}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><polyline points="15 18 9 12 15 6" /><polyline points="9 18 15 12 9 6" style={{ transform: 'translateX(6px)' }} /></svg>
          </div>
        </div>
      </div>
    </section>);

}

/* ---------------- Batch & scale ----------------
   Differentiator section between FeatureGrid and BeforeAfter.
   Left: editorial copy + three stat blocks + jump link.
   Right: dense full-bleed catalogue grid (5×6) that fades into the page edge. */
function BatchScale() {
  const { isMobile, isTablet } = useBreakpoint();

  /* Twelve-tile teaser — three rows × four columns on desktop, fully visible.
     Section min-height clamps up to 633px so it matches the FeatureGrid above. */
  const headerRow = [
  'assets/bulk-product1-front.jpg',
  'assets/bulk-product1-detail.jpg',
  'assets/bulk-product1-back.jpg',
  'assets/bulk-product1-move.jpg'];

  const secondRow = [
  'assets/bulk-product2-front.jpg',
  'assets/bulk-product2-detail.jpg',
  'assets/bulk-product2-back.jpg',
  'assets/bulk-product2-move.jpg'];

  const thirdRow = [
  'assets/bulk-product3-front.jpg',
  'assets/bulk-product3-detail.jpg',
  'assets/bulk-product3-back.jpg',
  'assets/bulk-product3-move.jpg'];

  const cells = [...headerRow, ...secondRow, ...thirdRow];
  const cols = isMobile ? 2 : 4;

  return (
    <section style={{
      background: 'var(--canvas)',
      padding: `clamp(48px, 7vw, 80px) var(--pad-x)`,
      minHeight: isMobile ? 'auto' : 633,
      display: 'flex', alignItems: 'center',
      position: 'relative'
    }}>
      <div style={{
        maxWidth: 'var(--container)', margin: '0 auto', width: '100%',
        display: 'grid',
        gridTemplateColumns: isMobile || isTablet ? '1fr' : 'minmax(0, 480px) 1fr',
        gap: 'clamp(32px, 5vw, 64px)',
        alignItems: 'center'
      }}>
        {/* ── LEFT — copy + single CTA ── */}
        <div style={{ maxWidth: 540, width: '100%' }}>
          <Eyebrow>Platform · 1.2</Eyebrow>
          <h2 style={{
            fontFamily: 'var(--font-display)', fontWeight: 400,
            fontSize: 'clamp(34px, 5.8vw, 56px)', lineHeight: 1.05, letterSpacing: '-0.03em',
            color: 'var(--ink)', margin: '20px 0 0', maxWidth: '14ch', textWrap: 'pretty'
          }}>
            From one product to <em style={{ fontStyle: 'italic', fontWeight: 700 }}>a thousand.</em>
          </h2>
          <p style={{
            marginTop: 24, maxWidth: 480,
            fontFamily: 'var(--font-sans)', fontSize: 'clamp(16px, 1.2vw, 19px)', lineHeight: 1.55,
            color: 'var(--graphite)'
          }}>Your entire catalogue, shot overnight. One brief, every SKU lit and framed the same, ready to drop into your website or campaign deck.

          </p>
          <div style={{ marginTop: 24 }}>
            <BatchLink to="/platform#batch-upload" label="See how it works" />
          </div>
        </div>

        {/* ── RIGHT — 4×3 teaser grid, fully visible (no bleed) ── */}
        <div style={{ position: 'relative', minWidth: 0 }}>
          <div style={{
            display: 'grid',
            gridTemplateColumns: `repeat(${cols}, 1fr)`,
            gap: 4
          }}>
            {cells.map((src, i) =>
            <BatchThumb key={i} src={src} />
            )}
          </div>
        </div>
      </div>
    </section>);

}

function BatchThumb({ src }) {
  const [hover, setHover] = React.useState(false);
  return (
    <div
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        aspectRatio: '4 / 5',
        background: 'var(--bone)',
        overflow: 'hidden',
        position: 'relative',
        transform: hover ? 'translateY(-2px)' : 'translateY(0)',
        boxShadow: hover ? '0 4px 14px rgba(0,0,0,0.12)' : 'none',
        transition: 'transform 200ms var(--ease-standard), box-shadow 200ms var(--ease-standard)',
        zIndex: hover ? 1 : 0
      }}>
      <img
        src={src}
        alt=""
        loading="lazy"
        style={{
          position: 'absolute', inset: 0,
          width: '100%', height: '100%',
          objectFit: 'cover', objectPosition: 'center',
          display: 'block'
        }} />
      
    </div>);

}

function BatchLink({ to = '/platform', label = 'See how batch processing works' }) {
  const [hover, setHover] = React.useState(false);
  return (
    <Link
      to={to}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        display: 'inline-flex', alignItems: 'center', gap: 6,
        fontFamily: 'var(--font-sans)', fontSize: 14, fontWeight: 600,
        color: 'var(--ink)', textDecoration: 'none',
        borderBottom: '1px solid var(--ink)',
        paddingBottom: 2
      }}>
      {label}
      <span aria-hidden="true" style={{
        display: 'inline-block',
        transform: hover ? 'translateX(4px)' : 'translateX(0)',
        transition: 'transform 200ms var(--ease-standard)'
      }}>→</span>
    </Link>);

}

/* ---------------- Video generation (Platform · 1.3) ----------------
   Same two-column editorial format as 1.1/1.2. Video frame on the left, copy on
   the right; a subtly distinct light surface (bone) sits between the canvas
   BatchScale and the paper SolutionsTeaser for gentle rhythm. */
function VideoGen() {
  const { isMobile } = useBreakpoint();
  return (
    <section style={{ background: 'var(--paper)', padding: 'var(--pad-y) var(--pad-x)' }}>
      <div style={{ maxWidth: 'var(--container)', margin: '0 auto', display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '0.9fr 1fr', gap: 'clamp(28px, 5vw, 72px)', alignItems: 'center' }}>
        <div style={{ order: 1 }}>
          <Eyebrow>Platform · 1.3</Eyebrow>
          <h2 style={{ fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 'clamp(34px, 5.8vw, 56px)', lineHeight: 1.05, letterSpacing: '-0.03em', color: 'var(--ink)', margin: '20px 0 0', maxWidth: '15ch' }}>
            Bring the look <em style={{ fontStyle: 'italic', fontWeight: 700 }}>to life.</em>
          </h2>
          <p style={{ marginTop: 24, fontSize: 'clamp(16px, 1.2vw, 19px)', lineHeight: 1.55, color: 'var(--graphite)', maxWidth: '42ch' }}>
            Generate short-form video from the same garment you already uploaded — a walk, a turn, fabric catching the light. Direct the motion once and export reels for social, ads and product pages.
          </p>
          <div style={{ marginTop: 28, display: 'flex', gap: 16, flexWrap: 'wrap', fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--slate)', letterSpacing: '0.04em', textTransform: 'uppercase' }}>
            <span>9:16</span><span>16:9</span><span>1:1</span><span>4:5</span>
          </div>
          <div style={{ marginTop: 28 }}>
            <BatchLink to="/platform" label="Explore video" />
          </div>
        </div>
        <div style={{ order: 2 }}>
          <VideoFrame />
        </div>
      </div>
    </section>);

}

function VideoFrame() {
  const videoRef = React.useRef(null);
  const loadedRef = React.useRef(false);
  React.useEffect(() => {
    const el = videoRef.current;
    if (!el) return;
    let cancelled = false;
    // The preview server doesn't support range requests, so a direct <video src>
    // fails (black frame). Fetch the file as a Blob and play from an object URL,
    // loaded lazily the first time the frame scrolls into view.
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach(async (e) => {
          if (e.isIntersecting) {
            if (!loadedRef.current) {
              loadedRef.current = true;
              try {
                const res = await fetch('assets/video-reel.mp4');
                const blob = await res.blob();
                if (cancelled) return;
                el.src = URL.createObjectURL(blob);
              } catch (err) {
                loadedRef.current = false;
                return;
              }
            }
            const p = el.play();
            if (p && p.catch) p.catch(() => {});
          } else {
            el.pause();
          }
        });
      },
      { threshold: 0.15 });

    io.observe(el);
    return () => { cancelled = true; io.disconnect(); };
  }, []);
  return (
    <div style={{ position: 'relative', aspectRatio: '4 / 5', overflow: 'hidden', background: 'var(--ink)' }}>
      <video
        ref={videoRef}
        muted
        loop
        playsInline
        preload="none"
        poster="assets/gallery-crosswalk.jpg"
        aria-label="ViZO — AI-generated fashion video"
        style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center', display: 'block' }} />

    </div>);

}

/* ---------------- Solutions teaser ---------------- */
function SolutionsTeaser() {
  return (
    <section style={{ background: 'var(--canvas)', padding: 'var(--pad-y) var(--pad-x)' }}>
      <div style={{ maxWidth: 'var(--container)', margin: '0 auto' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', flexWrap: 'wrap', gap: 24 }}>
          <div>
            <Eyebrow>Solutions</Eyebrow>
            <h2 style={{ fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 'clamp(34px, 5.8vw, 56px)', lineHeight: 1.05, letterSpacing: '-0.03em', color: 'var(--ink)', margin: '20px 0 0', maxWidth: '20ch' }}>Whatever's <em style={{ fontStyle: 'italic', fontWeight: 700 }}>holding you back.</em></h2>
            <p style={{ marginTop: 24, fontSize: 'clamp(15px, 1.5vw, 17px)', lineHeight: 1.6, color: 'var(--graphite)', maxWidth: '46ch' }}>
              Cost, speed, consistency, scale, representation, quality. ViZO is built to solve all six.
            </p>
          </div>
          <Link to="/solutions" style={{ fontFamily: 'var(--font-sans)', fontSize: 15, fontWeight: 600, color: 'var(--ink)', textDecoration: 'none', display: 'inline-flex', gap: 6 }}>See all solutions <span>→</span></Link>
        </div>
      </div>
    </section>);

}

/* ---------------- Gallery strip ---------------- */
/* Pulls from the same source as the Gallery page:
   user uploads (IndexedDB) first, then curated frames minus any hidden in localStorage.
   Anything added, removed, hidden or restored on /gallery shows up here next render. */
function HomeGalleryStrip() {
  const { isMobile, isTablet } = useBreakpoint();

  const merged = React.useMemo(() => window.GALLERY_ITEMS || [], []);

  const take = isTablet && !isMobile ? 3 : 4;
  const plates = merged.slice(0, take);

  return (
    <section style={{ padding: `clamp(40px, 6vw, 64px) var(--pad-x) clamp(64px, 10vw, 128px)`, background: 'var(--paper)' }}>
      <div style={{ maxWidth: 'var(--container)', margin: '0 auto' }}>
        <div style={{ padding: `0 0 clamp(28px, 5vw, 48px)`, display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', flexWrap: 'wrap', gap: 24 }}>
          <div>
            <Eyebrow>Gallery</Eyebrow>
            <h2 style={{
              fontFamily: 'var(--font-display)', fontWeight: 400,
              fontSize: 'clamp(28px, 4.4vw, 48px)', lineHeight: 1.1, letterSpacing: '-0.03em',
              color: 'var(--ink)', margin: '20px 0 0', maxWidth: 'none', textWrap: 'balance'
            }}>
              <span style={{ whiteSpace: 'nowrap' }}>One studio.</span>{' '}
              <em style={{ fontStyle: 'italic', fontWeight: 700, whiteSpace: 'nowrap', display: 'inline-block' }}>Endless possibilities.</em>
            </h2>
          </div>
          <Link to="/gallery" style={{ fontFamily: 'var(--font-sans)', fontSize: 15, fontWeight: 600, color: 'var(--ink)', textDecoration: 'none', display: 'inline-flex', gap: 6 }}>Open the gallery <span>→</span></Link>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: isMobile ? 'repeat(2, 1fr)' : isTablet ? 'repeat(3, 1fr)' : 'repeat(4, 1fr)', gap: isMobile ? 8 : 16 }}>
          {plates.map((p, i) =>
          <FashionPlate
            key={p.id || i}
            ratio={p.ratio || '3 / 4'}
            label=""
            subject=""
            src={p.src}
            position={p.position}
            fit={p.fit}
            bg={p.bg}
            idx={i} />
          )}
        </div>
      </div>
    </section>);

}

/* ---------------- Pricing teaser ---------------- */
function PricingTeaser() {
  const { isMobile } = useBreakpoint();
  return (
    <section style={{ background: 'var(--canvas)', padding: 'var(--pad-y) var(--pad-x)', borderTop: '1px solid var(--bone)' }}>
      <div style={{ maxWidth: 'var(--container)', margin: '0 auto', display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr', gap: 'clamp(28px, 4vw, 48px)', alignItems: 'center' }}>
        <div>
          <Eyebrow>Pricing</Eyebrow>
          <h2 style={{ fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 'clamp(34px, 5.8vw, 56px)', lineHeight: 1.05, letterSpacing: '-0.03em', color: 'var(--ink)', margin: '20px 0 0', maxWidth: '20ch', textWrap: 'pretty' }}>
            Plans that scale<br />with your <em style={{ fontStyle: 'italic', fontWeight: 700 }}>catalogue.</em>
          </h2>
          <p style={{ marginTop: 24, fontSize: 'clamp(15px, 1.5vw, 17px)', lineHeight: 1.6, color: 'var(--graphite)', maxWidth: '46ch' }}>Monthly credits that roll over. Top up any time. From boutiques to enterprise — there's a plan that matches your requirements.

          </p>
          <div style={{ marginTop: 28 }}>
            <Link to="/pricing"><Button variant="primary" size="large" arrow>See pricing</Button></Link>
          </div>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          {[
          { name: 'Standard', price: '£19.99', sub: '40 credits / mo' },
          { name: 'Plus', price: '£49.99', sub: '130 credits / mo' },
          { name: 'Premier', price: '£129.99', sub: '380 credits / mo', dark: true, featured: true },
          { name: 'Elite', price: '£299.99', sub: '1,000 credits / mo' }].
          map((t) =>
          <Link key={t.name} to="/pricing" style={{ textDecoration: 'none', color: 'inherit', display: 'block' }}>
            <div style={{
              background: t.dark ? 'var(--ink)' : 'var(--canvas)',
              color: t.dark ? 'var(--canvas)' : 'var(--ink)',
              border: t.dark ? 'none' : '1px solid var(--mist)',
              borderRadius: 10, padding: 24,
              position: 'relative',
              transition: 'transform 200ms var(--ease-standard), box-shadow 200ms var(--ease-standard)',
              cursor: 'pointer'
            }}
            onMouseEnter={(e) => {e.currentTarget.style.transform = 'translateY(-2px)';e.currentTarget.style.boxShadow = '0 4px 24px rgba(0,0,0,0.06)';}}
            onMouseLeave={(e) => {e.currentTarget.style.transform = 'translateY(0)';e.currentTarget.style.boxShadow = 'none';}}>
              {t.featured &&
              <span style={{ position: 'absolute', top: -10, left: 16 }}><Tag variant="featured">Popular</Tag></span>
              }
              <div style={{ fontFamily: 'var(--font-sans)', fontSize: 11, fontWeight: 600, letterSpacing: '0.12em', textTransform: 'uppercase', color: t.dark ? 'var(--ash)' : 'var(--graphite)' }}>{t.name}</div>
              <div style={{ marginTop: 12, fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 'clamp(30px, 3.2vw, 40px)', letterSpacing: '-0.03em', lineHeight: 1 }}>{t.price}</div>
              <div style={{ marginTop: 6, fontFamily: 'var(--font-mono)', fontSize: 12, color: t.dark ? 'var(--mist)' : 'var(--slate)' }}>{t.sub}</div>
            </div>
          </Link>
          )}
        </div>
      </div>
    </section>);

}

/* ---------------- Final CTA ---------------- */
function CTABand() {
  const { isMobile } = useBreakpoint();
  return (
    <section style={{ background: 'var(--ink)', color: 'var(--canvas)', padding: 'var(--pad-y) var(--pad-x)', textAlign: 'center' }}>
      <div style={{ maxWidth: 880, margin: '0 auto' }}>
        <Eyebrow color="var(--ash)">Start today</Eyebrow>
        <h2 style={{
          fontFamily: 'var(--font-display)', fontWeight: 300,
          fontSize: 'clamp(40px, 7.5vw, 80px)', lineHeight: 1.0, letterSpacing: '-0.04em',
          margin: '24px 0 0', color: 'var(--canvas)'
        }}>
          Your next campaign,<br /><em style={{ fontStyle: 'italic' }}>shot in an afternoon.</em>
        </h2>
        <p style={{ marginTop: 24, fontSize: 'clamp(15px, 1.6vw, 18px)', color: 'var(--mist)', maxWidth: '52ch', margin: '24px auto 0' }}>20 free credits when you sign up. No card, no contract, no reshoot.

        </p>
        <div style={{
          marginTop: 40,
          display: 'flex', flexDirection: isMobile ? 'column' : 'row',
          gap: 12, justifyContent: 'center', alignItems: isMobile ? 'stretch' : 'center',
          flexWrap: 'wrap'
        }}>
          <Button variant="primaryInv" size={isMobile ? 'large' : 'xl'} arrow onClick={() => {window.location.href = 'https://app.vizostudio.ai';}}>Start free trial</Button>
          <Link to="/contact"><Button variant="secondaryInv" size={isMobile ? 'large' : 'xl'}>Book a call</Button></Link>
        </div>
      </div>
    </section>);

}

Object.assign(window, { Hero, Marquee, FeatureGrid, BatchScale, BatchThumb, BatchLink, BeforeAfter, VideoGen, VideoFrame, SolutionsTeaser, HomeGalleryStrip, PricingTeaser, CTABand });