function useInView(ref, threshold = 0.15) {
  const [visible, setVisible] = React.useState(false);
  React.useEffect(() => {
    const obs = new IntersectionObserver(([e]) => { if (e.isIntersecting) setVisible(true); }, { threshold });
    if (ref.current) obs.observe(ref.current);
    return () => obs.disconnect();
  }, []);
  return visible;
}

function ShopPage({ coffees, onSelect }) {
  const [hovered, setHovered] = React.useState(null);

  return (
    <div style={{ paddingTop: 80 }}>

      {/* Page header */}
      <div style={{
        padding: '80px 48px 48px',
        borderBottom: '1px solid rgba(255,255,255,0.08)',
        display: 'grid',
        gridTemplateColumns: '1fr 1fr',
        alignItems: 'end',
        gap: 40,
      }}>
        <div>
          <div style={{ fontFamily: "'Montserrat', sans-serif", fontSize: 12, letterSpacing: '0.32em', color: 'rgba(255,255,255,0.28)', marginBottom: 16, textTransform: 'uppercase' }}>
            Current Harvest — {new Date().getFullYear()}
          </div>
          <h1 style={{
            fontFamily: "'Montserrat', sans-serif",
            fontSize: 'clamp(48px, 6vw, 80px)',
            fontWeight: 900, lineHeight: 1.05,
            letterSpacing: '-0.02em', color: '#ffffff',
          }}>
            <span className="reveal-line"><span className="reveal-line-inner" style={{ animationDelay: '0.08s' }}>The</span></span>
            <span className="reveal-line"><span className="reveal-line-inner" style={{ animationDelay: '0.22s' }}><em style={{ fontStyle: 'italic' }}>Origins</em></span></span>
          </h1>
        </div>
        <p style={{
          fontFamily: "'Montserrat', sans-serif",
          fontSize: 12, lineHeight: 2,
          color: 'rgba(255,255,255,0.45)',
          maxWidth: 420,
          borderLeft: '2px solid rgba(255,255,255,0.12)',
          paddingLeft: 24,
        }}>
          Four single-origin lots. Each sourced above 1,200 metres. Each roasted
          to the minimum necessary. Nothing added — everything earned by altitude,
          process, and the farmers who tend them.
        </p>
      </div>

      {/* Product grid */}
      <div style={{
        display: 'grid',
        gridTemplateColumns: '1fr 1fr',
      }}>
        {coffees.map((c, i) => {
          const isHovered = hovered === c.id;
          const isRight = i % 2 === 1;
          return (
            <div
              key={c.id}
              onClick={() => onSelect(c)}
              onMouseEnter={() => setHovered(c.id)}
              onMouseLeave={() => setHovered(null)}
              style={{
                padding: '56px 48px',
                borderRight: !isRight ? '1px solid rgba(255,255,255,0.08)' : 'none',
                borderBottom: i < 2 ? '1px solid rgba(255,255,255,0.08)' : 'none',
                cursor: 'crosshair',
                background: isHovered ? '#ffffff' : 'transparent',
                transition: 'background 0.45s cubic-bezier(0.25,0.46,0.45,0.94)',
                animation: `appleReveal 0.8s cubic-bezier(0.25,0.46,0.45,0.94) ${i * 0.12}s both`,
                position: 'relative',
                overflow: 'hidden',
              }}
            >
              {/* Large ghost index */}
              <div aria-hidden="true" style={{
                position: 'absolute', top: -10, right: 32,
                fontFamily: "'Montserrat', sans-serif",
                fontSize: 140, fontWeight: 900,
                color: isHovered ? 'rgba(0,0,0,0.06)' : 'rgba(255,255,255,0.04)',
                lineHeight: 1, userSelect: 'none', pointerEvents: 'none',
                transition: 'color 0.2s',
              }}>{c.index}</div>

              {/* Content */}
              <div style={{ position: 'relative' }}>
                <div style={{ fontFamily: "'Montserrat', sans-serif", fontSize: 12, letterSpacing: '0.22em', color: isHovered ? 'rgba(0,0,0,0.38)' : 'rgba(255,255,255,0.3)', marginBottom: 14, textTransform: 'uppercase', transition: 'color 0.2s' }}>
                  {c.process} · {c.altitude.toLocaleString()}m
                </div>

                <h2 style={{
                  fontFamily: "'Montserrat', sans-serif",
                  fontSize: 'clamp(32px, 3.5vw, 52px)',
                  fontWeight: 900, letterSpacing: '-0.02em', lineHeight: 0.9,
                  color: isHovered ? '#000000' : '#ffffff',
                  transition: 'color 0.2s', marginBottom: 8,
                }}>{c.name}</h2>

                <div style={{ fontFamily: "'Montserrat', sans-serif", fontSize: 12, letterSpacing: '0.12em', color: isHovered ? 'rgba(0,0,0,0.45)' : 'rgba(255,255,255,0.38)', transition: 'color 0.2s', marginBottom: 28, textTransform: 'uppercase' }}>
                  {c.region} · {c.origin}
                </div>

                {/* Notes */}
                <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 32 }}>
                  {c.notes.map((n, ni) => (
                    <span key={ni} style={{
                      fontFamily: "'Montserrat', sans-serif",
                      fontSize: 12, letterSpacing: '0.15em',
                      padding: '5px 10px',
                      border: `1px solid ${isHovered ? 'rgba(0,0,0,0.2)' : 'rgba(255,255,255,0.18)'}`,
                      color: isHovered ? 'rgba(0,0,0,0.6)' : 'rgba(255,255,255,0.5)',
                      transition: 'all 0.2s',
                      textTransform: 'uppercase',
                    }}>{n}</span>
                  ))}
                </div>

                {/* Price + CTA */}
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                  <div>
                    <div style={{ fontFamily: "'Montserrat', sans-serif", fontSize: 12, letterSpacing: '0.2em', color: isHovered ? 'rgba(0,0,0,0.35)' : 'rgba(255,255,255,0.28)', marginBottom: 4 }}>FROM</div>
                    <div style={{ fontFamily: "'Montserrat', sans-serif", fontSize: 28, fontWeight: 700, color: isHovered ? '#000000' : '#ffffff', transition: 'color 0.2s', lineHeight: 1 }}>
                      ${c.prices['100g']}
                    </div>
                  </div>
                  <div style={{
                    fontFamily: "'Montserrat', sans-serif",
                    fontSize: 12, letterSpacing: '0.22em',
                    padding: '12px 24px',
                    border: `1px solid ${isHovered ? 'rgba(0,0,0,0.5)' : 'rgba(255,255,255,0.3)'}`,
                    color: isHovered ? '#000000' : '#ffffff',
                    transition: 'all 0.2s',
                    display: 'flex', alignItems: 'center', gap: 10,
                  }}>
                    SELECT <span style={{ transform: isHovered ? 'translateX(3px)' : 'translateX(0)', display: 'inline-block', transition: 'transform 0.2s' }}>→</span>
                  </div>
                </div>
              </div>
            </div>
          );
        })}
      </div>

      {/* Shipping note */}
      <div style={{
        borderTop: '1px solid rgba(255,255,255,0.08)',
        padding: '32px 48px',
        display: 'flex', gap: 64,
      }}>
        {[
          ['FREE SHIPPING', 'On all orders over $120'],
          ['ROASTED TO ORDER', 'Dispatched within 48 hours'],
          ['FRESHNESS WINDOW', 'Best 10–28 days post-roast'],
        ].map(([title, sub]) => (
          <div key={title}>
            <div style={{ fontFamily: "'Montserrat', sans-serif", fontSize: 12, letterSpacing: '0.22em', color: 'rgba(255,255,255,0.5)', marginBottom: 4 }}>{title}</div>
            <div style={{ fontFamily: "'Montserrat', sans-serif", fontSize: 12, color: 'rgba(255,255,255,0.28)' }}>{sub}</div>
          </div>
        ))}
      </div>

    </div>
  );
}

Object.assign(window, { ShopPage });
