// V2 — "Zine"
// Collage / editorial / riso-zine vibe. Same cool & moody palette but composed
// as a zine: marquee, taped polaroids, hand-cut stickers, hover-spin shapes.
// No emoji. Draggable polaroids in "Now" section. Type "vidya" for confetti.

const zinePalette = {
  bg: 'var(--tw-bg, #0d1530)',          // deep navy
  paper: 'var(--tw-paper, #f2ead7)',    // warm cream paper (accent surfaces)
  ink: '#f4f1e8',         // off-white text on dark
  inkDim: '#8a98be',      // dusty blue-gray
  inkOnPaper: '#1a2142',  // dark on cream
  line: '#1e294a',
  accent: 'var(--tw-accent, #ed6a5a)',  // dusty coral/red — punch color
  blue: '#4d7fc9',        // dusty blue
  mustard: '#d4a83a',     // mustard
  sage: '#6b9a7f',        // dusty sage
  plum: '#7d5b9f',        // dusty plum
};

// ---------- Responsive hook ----------
function useIsMobile(bp = 760) {
  const [m, setM] = React.useState(typeof window !== 'undefined' ? window.innerWidth < bp : false);
  React.useEffect(() => {
    const on = () => setM(window.innerWidth < bp);
    on();
    window.addEventListener('resize', on);
    return () => window.removeEventListener('resize', on);
  }, [bp]);
  return m;
}

// ---------- Glyphs (reuse V1 style) ----------
const ZGlyph = ({ name, size = 16, color = 'currentColor', sw = 1.75 }) => {
  const common = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: color, strokeWidth: sw, strokeLinecap: 'round', strokeLinejoin: 'round' };
  const p = {
    star: <path d="M12 3l2 6h6l-5 4 2 7-5-4-5 4 2-7-5-4h6z"/>,
    asterisk: <><path d="M12 3v18M3 12h18M5 5l14 14M19 5l-14 14"/></>,
    arrow: <><path d="M5 12h14M13 5l7 7-7 7"/></>,
    scissors: <><circle cx="6" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M8.1 8.1L20 20M8.1 15.9L20 4"/></>,
    eye: <><path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7-10-7-10-7z"/><circle cx="12" cy="12" r="3"/></>,
    tag: <><path d="M3 3h8l10 10-8 8L3 11V3z"/><circle cx="7" cy="7" r="1.5"/></>,
    circle: <circle cx="12" cy="12" r="9"/>,
    note: <><path d="M9 18V5l12-2v13"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/></>,
    cam: <><path d="M3 8h4l2-3h6l2 3h4v12H3z"/><circle cx="12" cy="13" r="4"/></>,
    flag: <><path d="M5 21V4h14l-3 4 3 4H5"/></>,
  };
  return <svg {...common}>{p[name]}</svg>;
};

// ---------- Shapes for zine ----------
const ZShape = ({ type, size = 80, color, sw = 3, style = {} }) => {
  const s = size;
  if (type === 'riso-circle') {
    return (
      <svg width={s} height={s} viewBox="0 0 100 100" style={style}>
        <defs><pattern id={`dots-${color.replace('#','')}`} width="5" height="5" patternUnits="userSpaceOnUse">
          <circle cx="2" cy="2" r="0.8" fill={color}/>
        </pattern></defs>
        <circle cx="50" cy="50" r="46" fill={`url(#dots-${color.replace('#','')})`} stroke={color} strokeWidth="2" opacity="0.9"/>
      </svg>
    );
  }
  if (type === 'cut-star') {
    return (
      <svg width={s} height={s} viewBox="0 0 100 100" style={style}>
        <path d="M50 5 L62 38 L96 42 L70 64 L79 96 L50 78 L21 96 L30 64 L4 42 L38 38 Z" fill={color}/>
      </svg>
    );
  }
  if (type === 'cloud') {
    return (
      <svg width={s} height={s} viewBox="0 0 120 80" style={style}>
        <path d="M25 60 Q10 60 10 45 Q10 30 25 30 Q28 15 45 15 Q60 15 65 28 Q80 25 90 35 Q110 35 110 50 Q110 65 90 65 L30 65 Q25 65 25 60 Z" fill={color}/>
      </svg>
    );
  }
  if (type === 'half') {
    return (
      <svg width={s} height={s} viewBox="0 0 100 100" style={style}>
        <path d="M50 5 A 45 45 0 0 1 50 95 Z" fill={color}/>
      </svg>
    );
  }
  if (type === 'wave') {
    return (
      <svg width={s * 1.5} height={s * 0.4} viewBox="0 0 150 40" style={style}>
        <path d="M5 20 Q 20 4, 37.5 20 T 75 20 T 112.5 20 T 145 20" fill="none" stroke={color} strokeWidth={sw} strokeLinecap="round"/>
      </svg>
    );
  }
  if (type === 'arch') {
    return (
      <svg width={s} height={s} viewBox="0 0 100 100" style={style}>
        <path d="M10 95 L10 55 A 40 40 0 0 1 90 55 L90 95 Z" fill={color}/>
      </svg>
    );
  }
  if (type === 'eye') {
    return (
      <svg width={s} height={s * 0.6} viewBox="0 0 100 60" style={style}>
        <ellipse cx="50" cy="30" rx="46" ry="24" fill="#f4f1e8" stroke={color} strokeWidth="3"/>
        <circle cx="50" cy="30" r="14" fill={color}/>
        <circle cx="54" cy="26" r="4" fill="#f4f1e8"/>
      </svg>
    );
  }
  return null;
};

// ---------- Tape strip ----------
const Tape = ({ width = 100, rotation = 0, color = 'rgba(212, 168, 58, 0.5)', style = {} }) => (
  <div style={{
    width, height: 24, background: color,
    borderLeft: '1px dashed rgba(0,0,0,0.1)', borderRight: '1px dashed rgba(0,0,0,0.1)',
    transform: `rotate(${rotation}deg)`, ...style,
  }}/>
);

// ---------- Spinny hover wrapper ----------
function HoverSpin({ children, deg = 20, style = {} }) {
  const [hovered, setHovered] = React.useState(false);
  return (
    <div
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
      style={{
        transition: 'transform 0.5s cubic-bezier(0.16, 1, 0.3, 1)',
        transform: hovered ? `rotate(${deg}deg) scale(1.1)` : 'rotate(0deg) scale(1)',
        ...style,
      }}
    >
      {children}
    </div>
  );
}

// ---------- Draggable (simple, for polaroids) ----------
function ZDraggable({ initX, initY, rot = 0, children, onPick }) {
  const [pos, setPos] = React.useState({ x: initX, y: initY });
  const [dragging, setDragging] = React.useState(false);
  const [z, setZ] = React.useState(1);
  const offsetRef = React.useRef({ dx: 0, dy: 0 });
  const nodeRef = React.useRef(null);

  const onMouseDown = (e) => {
    e.preventDefault();
    const rect = nodeRef.current.getBoundingClientRect();
    const pRect = nodeRef.current.parentElement.getBoundingClientRect();
    offsetRef.current = { dx: e.clientX - rect.left, dy: e.clientY - rect.top, pL: pRect.left, pT: pRect.top };
    setDragging(true);
    setZ(999);
    onPick && onPick();
  };
  React.useEffect(() => {
    if (!dragging) return;
    const move = (e) => {
      const { dx, dy, pL, pT } = offsetRef.current;
      setPos({ x: e.clientX - pL - dx, y: e.clientY - pT - dy });
    };
    const up = () => setDragging(false);
    window.addEventListener('mousemove', move);
    window.addEventListener('mouseup', up);
    return () => { window.removeEventListener('mousemove', move); window.removeEventListener('mouseup', up); };
  }, [dragging]);
  return (
    <div ref={nodeRef} onMouseDown={onMouseDown} style={{
      position: 'absolute', left: pos.x, top: pos.y, zIndex: z,
      cursor: dragging ? 'grabbing' : 'grab', transform: `rotate(${rot}deg)`,
      transition: dragging ? 'none' : 'transform 0.2s',
      userSelect: 'none',
    }}>
      {children}
    </div>
  );
}

// ---------- Marquee ----------
function Marquee({ items, color, speed = 30 }) {
  return (
    <div style={{ overflow: 'hidden', width: '100%' }}>
      <div style={{
        display: 'flex', gap: 40, whiteSpace: 'nowrap',
        animation: `scroll-left ${speed}s linear infinite`,
        fontFamily: 'Fraunces', fontSize: 'clamp(36px, 9vw, 80px)', fontWeight: 700, fontStyle: 'italic',
        color, letterSpacing: '-0.03em',
      }}>
        {[...items, ...items, ...items].map((it, i) => (
          <span key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: 40 }}>
            {it}
            <span style={{ display: 'inline-block', width: 18, height: 18, borderRadius: '50%', background: zinePalette.accent, marginTop: 4 }}/>
          </span>
        ))}
      </div>
      <style>{`
        @keyframes scroll-left {
          from { transform: translateX(0); }
          to { transform: translateX(-33.33%); }
        }
      `}</style>
    </div>
  );
}

// ---------- Hero ----------
function ZineHero({ tweaks = {} }) {
  const containerRef = React.useRef(null);
  const isMobile = useIsMobile();
  return (
    <div style={{
      background: zinePalette.bg, color: zinePalette.ink,
      position: 'relative', minHeight: isMobile ? 'auto' : 760, overflow: 'hidden',
      padding: isMobile ? '20px 20px 48px' : '32px 48px 60px',
    }} ref={containerRef}>
      {/* grainy noise overlay */}
      {tweaks.grain !== false && <div style={{
        position: 'absolute', inset: 0, pointerEvents: 'none', opacity: 0.15,
        background: `url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E")`,
      }}/>}
      <div style={{
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        borderBottom: `1px solid ${zinePalette.line}`, paddingBottom: isMobile ? 14 : 20, marginBottom: 20,
        position: 'relative', zIndex: 5, gap: 12, flexWrap: 'wrap',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          <ZShape type="cut-star" size={28} color={zinePalette.accent} style={{ display: 'block' }}/>
          <div style={{ fontFamily: 'Fraunces', fontSize: 22, fontWeight: 700, fontStyle: 'italic', letterSpacing: '-0.02em' }}>
            vidya<span style={{ color: zinePalette.accent, fontStyle: 'normal' }}>*</span>zine
          </div>
          {!isMobile && <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 11, color: zinePalette.inkDim, marginLeft: 20, letterSpacing: '0.1em' }}>
            ISSUE 01 · SPRING 2026
          </div>}
        </div>
        <nav style={{ display: 'flex', gap: isMobile ? 16 : 28, flexWrap: 'wrap' }}>
          {['home', 'about', 'projects', 'now', 'interests'].map((l) => (
            <a key={l} href={`#${l}`} style={{
              color: zinePalette.ink, fontFamily: 'Fraunces', fontSize: isMobile ? 14 : 16, fontStyle: 'italic',
              textDecoration: 'underline', textDecorationColor: zinePalette.line,
              textUnderlineOffset: 4, transition: 'all 0.2s',
            }}
            onMouseEnter={(e) => { e.currentTarget.style.textDecorationColor = zinePalette.accent; e.currentTarget.style.color = zinePalette.accent; }}
            onMouseLeave={(e) => { e.currentTarget.style.textDecorationColor = zinePalette.line; e.currentTarget.style.color = zinePalette.ink; }}>
              {l}
            </a>
          ))}
        </nav>
      </div>

      {/* Header band: issue/price */}
      <div style={{
        display: 'flex', justifyContent: 'space-between', flexWrap: 'wrap', gap: 8,
        fontFamily: 'JetBrains Mono, monospace',
        fontSize: isMobile ? 9 : 11, color: zinePalette.inkDim, letterSpacing: isMobile ? '0.1em' : '0.2em', textTransform: 'uppercase',
        marginBottom: isMobile ? 40 : 60, position: 'relative', zIndex: 5,
      }}>
        <span>VOL.01 · A COLOURFUL LITTLE CORNER OF THE INTERNET</span>
        {!isMobile && <span>NEW DELHI → EVERYWHERE</span>}
        <span>PRICE: A SMILE</span>
      </div>

      {/* Cover — giant italic name with collage */}
      <div style={{ position: 'relative', zIndex: 5, textAlign: 'center', marginBottom: 40 }}>
        <div style={{
          fontFamily: 'Fraunces', fontSize: 22, fontStyle: 'italic', color: zinePalette.inkDim, marginBottom: 8,
        }}>
          featuring —
        </div>
        <h1 style={{
          fontFamily: 'Fraunces', fontSize: 'clamp(72px, 22vw, 240px)', fontStyle: 'italic', fontWeight: 800, margin: 0,
          lineHeight: 0.9, letterSpacing: '-0.05em', color: zinePalette.ink,
          textShadow: `var(--tw-cover-shadow, 8px) var(--tw-cover-shadow, 8px) 0 ${zinePalette.accent}`,
        }}>
          vidya
        </h1>
        <div style={{
          fontFamily: 'Fraunces', fontSize: 'clamp(17px, 4.5vw, 28px)', fontWeight: 500, color: zinePalette.mustard, marginTop: 16,
          letterSpacing: '-0.01em',
        }}>
          &mdash; a student, a builder, a smiler. &mdash;
        </div>
      </div>

      {/* Floating collage elements — hidden on mobile to keep the cover clean */}
      {!isMobile && <React.Fragment>
      <div style={{ position: 'absolute', top: 180, left: 40, zIndex: 4 }}>
        <HoverSpin deg={25}>
          <ZShape type="cut-star" size={110} color={zinePalette.mustard}/>
        </HoverSpin>
      </div>
      <div style={{ position: 'absolute', top: 220, right: 60, zIndex: 4 }}>
        <HoverSpin deg={-30}>
          <ZShape type="riso-circle" size={130} color={zinePalette.blue}/>
        </HoverSpin>
      </div>
      <div style={{ position: 'absolute', top: 380, left: 80, zIndex: 4 }}>
        <HoverSpin deg={15}>
          <ZShape type="eye" size={90} color={zinePalette.accent}/>
        </HoverSpin>
      </div>
      <div style={{ position: 'absolute', top: 420, right: 100, zIndex: 4 }}>
        <HoverSpin deg={-20}>
          <ZShape type="arch" size={80} color={zinePalette.sage}/>
        </HoverSpin>
      </div>
      <div style={{ position: 'absolute', top: 520, left: '50%', transform: 'translateX(-50%)', zIndex: 4, opacity: 0.8 }}>
        <ZShape type="wave" size={400} color={zinePalette.plum} sw={6}/>
      </div>
      </React.Fragment>}

      {/* On mobile, a single playful row of stickers under the cover */}
      {isMobile && <div style={{ display: 'flex', justifyContent: 'center', gap: 18, marginBottom: 36, position: 'relative', zIndex: 5 }}>
        <ZShape type="cut-star" size={48} color={zinePalette.mustard}/>
        <ZShape type="riso-circle" size={48} color={zinePalette.blue}/>
        <ZShape type="eye" size={52} color={zinePalette.accent}/>
        <ZShape type="arch" size={44} color={zinePalette.sage}/>
      </div>}

      {/* CTAs */}
      <div style={{
        position: 'relative', zIndex: 5, display: 'flex', justifyContent: 'center', gap: 16,
        marginTop: isMobile ? 8 : 100, flexWrap: 'wrap',
      }}>
        <a href="#projects" style={{
          background: zinePalette.accent, color: zinePalette.ink, padding: '16px 32px',
          fontFamily: 'Fraunces', fontSize: 18, fontStyle: 'italic', fontWeight: 600,
          textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 10,
          border: `2px solid ${zinePalette.ink}`, boxShadow: `6px 6px 0 ${zinePalette.ink}`,
          transition: 'all 0.15s',
        }}
        onMouseEnter={(e) => { e.currentTarget.style.transform = 'translate(-2px, -2px)'; e.currentTarget.style.boxShadow = `8px 8px 0 ${zinePalette.ink}`; }}
        onMouseLeave={(e) => { e.currentTarget.style.transform = 'translate(0, 0)'; e.currentTarget.style.boxShadow = `6px 6px 0 ${zinePalette.ink}`; }}>
          flip through &rarr;
        </a>
        <a href="#about" style={{
          background: 'transparent', color: zinePalette.ink, padding: '16px 32px',
          fontFamily: 'Fraunces', fontSize: 18, fontStyle: 'italic', fontWeight: 500,
          textDecoration: 'none', border: `2px solid ${zinePalette.ink}`,
        }}>
          about the author
        </a>
      </div>

      <div style={{
        position: isMobile ? 'relative' : 'absolute', marginTop: isMobile ? 36 : 0,
        bottom: isMobile ? 'auto' : 20, left: isMobile ? 'auto' : 48, right: isMobile ? 'auto' : 48,
        display: 'flex', justifyContent: 'space-between', flexWrap: 'wrap', gap: 8,
        fontFamily: 'JetBrains Mono, monospace', fontSize: isMobile ? 9 : 11, color: zinePalette.inkDim, letterSpacing: '0.2em',
      }}>
        <span>P.01 · COVER</span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
          <ZGlyph name="asterisk" size={12}/> TIP: TYPE &ldquo;VIDYA&rdquo;
        </span>
        <span>SCROLL ↓</span>
      </div>
    </div>
  );
}

// ---------- About ----------
function ZineAbout() {
  const isMobile = useIsMobile();
  return (
    <section id="about" style={{
      background: zinePalette.paper, color: zinePalette.inkOnPaper,
      padding: isMobile ? '60px 20px' : '100px 80px', position: 'relative', overflow: 'hidden',
    }}>
      {/* Page number header */}
      <div style={{
        display: 'flex', justifyContent: 'space-between', borderBottom: `1px solid ${zinePalette.inkOnPaper}`,
        paddingBottom: 12, marginBottom: isMobile ? 36 : 60, fontFamily: 'JetBrains Mono, monospace', fontSize: isMobile ? 9 : 11,
        color: zinePalette.inkOnPaper, letterSpacing: isMobile ? '0.1em' : '0.2em', textTransform: 'uppercase', opacity: 0.7, gap: 8,
      }}>
        <span>P.02 · ABOUT</span>
        {!isMobile && <span>&mdash; nice to meet you &mdash;</span>}
        <span>2026</span>
      </div>

      <div style={{ maxWidth: 1100, margin: '0 auto', display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1.1fr 1fr', gap: isMobile ? 48 : 60, alignItems: 'start' }}>
        <div>
          <div style={{
            fontFamily: 'Fraunces', fontSize: 22, fontStyle: 'italic', color: zinePalette.accent,
            marginBottom: 12, display: 'inline-flex', alignItems: 'center', gap: 10,
          }}>
            <ZGlyph name="star" size={16} color={zinePalette.accent}/> so, about me —
          </div>
          <h2 style={{
            fontFamily: 'Fraunces', fontSize: 'clamp(44px, 9vw, 84px)', fontWeight: 700, lineHeight: 0.95, margin: 0,
            letterSpacing: '-0.03em', color: zinePalette.inkOnPaper,
          }}>
            hi, I&rsquo;m <em style={{ fontStyle: 'italic', color: zinePalette.accent }}>Vidya</em>.
          </h2>
          <div style={{
            fontFamily: 'Fraunces', fontSize: 'clamp(18px, 4.5vw, 28px)', fontStyle: 'italic', color: zinePalette.blue, marginTop: 12,
          }}>
            my name means <span style={{
              background: zinePalette.mustard, padding: '2px 12px', color: zinePalette.inkOnPaper, fontStyle: 'normal', fontWeight: 600,
            }}>knowledge</span> in Sanskrit.
          </div>

          <div style={{ marginTop: 40, display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr', gap: isMobile ? 20 : 32 }}>
            <p style={{ fontSize: 16, lineHeight: 1.7, color: zinePalette.inkOnPaper, margin: 0 }}>
              I&rsquo;m a comp-sci student who collects small obsessions: old graphic design books, extremely specific spotify playlists, focaccia recipes. this site is one of them.
            </p>
            <p style={{ fontSize: 16, lineHeight: 1.7, color: zinePalette.inkOnPaper, margin: 0 }}>
              I made everything you see here by hand &mdash; HTML, CSS, and JavaScript. it&rsquo;s a little messy in places, which feels honest.
            </p>
          </div>

          {/* Signature line */}
          <div style={{
            marginTop: 48, fontFamily: 'Fraunces', fontSize: 42, fontStyle: 'italic', fontWeight: 500,
            color: zinePalette.accent, borderTop: `1px solid ${zinePalette.inkOnPaper}`, paddingTop: 24,
            opacity: 0.9,
          }}>
            &mdash; v.
          </div>
        </div>

        {/* Portrait collage */}
        <div style={{ position: 'relative', minHeight: isMobile ? 'auto' : 520 }}>
          {isMobile ? (
            /* Mobile: clean stacked layout, no absolute overlaps */
            <div style={{ display: 'flex', flexDirection: 'column', gap: 24, alignItems: 'center' }}>
              <div style={{
                width: '100%', maxWidth: 300, aspectRatio: '4/5',
                background: `repeating-linear-gradient(0deg, #dcd3bd, #dcd3bd 6px, #d2c9b1 6px, #d2c9b1 12px)`,
                transform: 'rotate(2deg)', boxShadow: `6px 6px 0 ${zinePalette.inkOnPaper}`, padding: 14, position: 'relative',
              }}>
                <div style={{
                  width: '100%', height: '100%', background: zinePalette.blue,
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  fontFamily: 'JetBrains Mono, monospace', fontSize: 11, color: zinePalette.paper, letterSpacing: '0.2em',
                }}>[ PORTRAIT ]</div>
                <Tape width={90} rotation={-4} color="rgba(237, 106, 90, 0.4)" style={{ position: 'absolute', top: -10, left: '30%' }}/>
              </div>
              <div style={{
                width: '100%', maxWidth: 300, background: zinePalette.ink, color: zinePalette.inkOnPaper,
                padding: '20px 18px', transform: 'rotate(-2deg)', boxShadow: `5px 5px 0 ${zinePalette.accent}`,
                fontFamily: 'Fraunces', fontStyle: 'italic', fontSize: 17, lineHeight: 1.4, position: 'relative',
              }}>
                &ldquo;smiling all the time&rdquo;
                <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 10, fontStyle: 'normal', color: zinePalette.inkDim, marginTop: 10, letterSpacing: '0.2em' }}>— mom, probably</div>
              </div>
              <div style={{
                fontFamily: 'Fraunces', fontStyle: 'italic', fontSize: 16, color: zinePalette.inkOnPaper,
                lineHeight: 1.9, alignSelf: 'flex-start',
              }}>
                <div>studies → comp-sci</div>
                <div>currently → year 2</div>
                <div>vibe → <span style={{ color: zinePalette.accent }}>✦ unbothered</span></div>
                <div>superpower → focaccia</div>
              </div>
            </div>
          ) : (
          <React.Fragment>
          {/* Big portrait */}
          <div style={{
            position: 'absolute', top: 0, right: 0, width: 320, aspectRatio: '4/5',
            background: `repeating-linear-gradient(0deg, #dcd3bd, #dcd3bd 6px, #d2c9b1 6px, #d2c9b1 12px)`,
            transform: 'rotate(3deg)', boxShadow: `8px 8px 0 ${zinePalette.inkOnPaper}`,
            padding: 16,
          }}>
            <div style={{
              width: '100%', height: '100%', background: zinePalette.blue,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontFamily: 'JetBrains Mono, monospace', fontSize: 11, color: zinePalette.paper,
              letterSpacing: '0.2em',
            }}>
              [ PORTRAIT ]
            </div>
            <Tape width={90} rotation={-4} color="rgba(237, 106, 90, 0.4)" style={{
              position: 'absolute', top: -10, left: '30%',
            }}/>
          </div>

          {/* Taped note */}
          <div style={{
            position: 'absolute', top: 60, left: 0, width: 220, background: zinePalette.ink,
            color: zinePalette.inkOnPaper, padding: '20px 18px', transform: 'rotate(-4deg)',
            boxShadow: `5px 5px 0 ${zinePalette.accent}`, fontFamily: 'Fraunces', fontStyle: 'italic',
            fontSize: 17, lineHeight: 1.4,
          }}>
            &ldquo;smiling all the time&rdquo;
            <div style={{
              fontFamily: 'JetBrains Mono, monospace', fontSize: 10, fontStyle: 'normal',
              color: zinePalette.inkDim, marginTop: 10, letterSpacing: '0.2em',
            }}>— mom, probably</div>
            <Tape width={60} rotation={8} color="rgba(212, 168, 58, 0.6)" style={{
              position: 'absolute', top: -8, right: 20,
            }}/>
          </div>

          {/* Sticker */}
          <div style={{ position: 'absolute', bottom: 40, left: 60 }}>
            <HoverSpin deg={30}>
              <ZShape type="cut-star" size={90} color={zinePalette.accent}/>
            </HoverSpin>
          </div>

          {/* Hand-written quick facts */}
          <div style={{
            position: 'absolute', bottom: 0, right: 20, width: 180,
            fontFamily: 'Fraunces', fontStyle: 'italic', fontSize: 15, color: zinePalette.inkOnPaper,
            lineHeight: 1.8, transform: 'rotate(-2deg)',
          }}>
            <div>studies → comp-sci</div>
            <div>currently → year 2</div>
            <div>vibe → <span style={{ color: zinePalette.accent }}>✦ unbothered</span></div>
            <div>superpower → focaccia</div>
          </div>
          </React.Fragment>
          )}
        </div>
      </div>
    </section>
  );
}

// ---------- Marquee band ----------
function ZineMarquee() {
  return (
    <div style={{
      background: zinePalette.accent, color: zinePalette.ink, padding: '20px 0',
      borderTop: `3px solid ${zinePalette.ink}`, borderBottom: `3px solid ${zinePalette.ink}`,
    }}>
      <Marquee items={['making things', 'breaking things', 'writing stuff', 'reading stuff', 'trying stuff']} color={zinePalette.ink}/>
    </div>
  );
}

// ---------- Projects ----------
function ZineProjects() {
  const isMobile = useIsMobile();
  const projects = [
    { n: '01', title: 'tiny library', tag: 'web app · 2025', desc: 'a catalogue of every book I&rsquo;ve ever loved, built from scratch with vanilla JS. searchable, taggable, way over-engineered.', color: zinePalette.accent, shape: 'arch' },
    { n: '02', title: 'daily doodle', tag: 'art practice · ongoing', desc: 'one procreate doodle every day for 100 days. currently on day 43. some are good. most are not.', color: zinePalette.mustard, shape: 'riso-circle' },
    { n: '03', title: 'hostel cookbook', tag: 'zine · 2025', desc: 'recipes my friends and I actually cook at 11pm in a tiny kitchen. hand-lettered, risograph printed.', color: zinePalette.sage, shape: 'cut-star' },
    { n: '04', title: 'starry.css', tag: 'open source · 2024', desc: 'a tiny CSS library for making constellation backgrounds using only box-shadows. 47 stars on github.', color: zinePalette.plum, shape: 'cloud' },
  ];

  return (
    <section id="projects" style={{
      background: zinePalette.bg, color: zinePalette.ink,
      padding: isMobile ? '60px 20px' : '100px 80px', position: 'relative', overflow: 'hidden',
    }}>
      <div style={{
        display: 'flex', justifyContent: 'space-between', borderBottom: `1px solid ${zinePalette.line}`,
        paddingBottom: 12, marginBottom: isMobile ? 36 : 60, fontFamily: 'JetBrains Mono, monospace', fontSize: isMobile ? 9 : 11,
        color: zinePalette.inkDim, letterSpacing: isMobile ? '0.1em' : '0.2em', textTransform: 'uppercase', gap: 8,
      }}>
        <span>P.03 · PORTFOLIO</span>
        {!isMobile && <span>&mdash; things made with care &mdash;</span>}
        <span>04 ENTRIES</span>
      </div>

      <div style={{ maxWidth: 1100, margin: '0 auto 60px', textAlign: 'center' }}>
        <div style={{
          fontFamily: 'Fraunces', fontSize: 22, fontStyle: 'italic', color: zinePalette.accent,
          marginBottom: 8,
        }}>
          in this issue —
        </div>
        <h2 style={{
          fontFamily: 'Fraunces', fontSize: 'clamp(44px, 11vw, 96px)', fontWeight: 700, margin: 0, lineHeight: 0.95,
          letterSpacing: '-0.03em',
        }}>
          some <em style={{ fontStyle: 'italic', color: zinePalette.mustard }}>things</em> I made.
        </h2>
      </div>

      <div style={{ maxWidth: 1100, margin: '0 auto', display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr', gap: isMobile ? 28 : 32 }}>
        {projects.map((p, i) => (
          <article key={i} style={{
            background: zinePalette.paper, color: zinePalette.inkOnPaper,
            padding: 32, position: 'relative', overflow: 'hidden',
            boxShadow: `10px 10px 0 ${zinePalette.accent}`,
            transform: i % 2 === 0 ? 'rotate(-0.8deg)' : 'rotate(0.6deg)',
            transition: 'transform 0.3s',
            cursor: 'pointer',
          }}
          onMouseEnter={(e) => { e.currentTarget.style.transform = 'rotate(0deg) translateY(-6px)'; }}
          onMouseLeave={(e) => { e.currentTarget.style.transform = i % 2 === 0 ? 'rotate(-0.8deg)' : 'rotate(0.6deg)'; }}>
            {/* Header row */}
            <div style={{
              display: 'flex', justifyContent: 'space-between', alignItems: 'center',
              borderBottom: `1px dashed ${zinePalette.inkOnPaper}`, paddingBottom: 12, marginBottom: 24,
              fontFamily: 'JetBrains Mono, monospace', fontSize: 11, letterSpacing: '0.2em', textTransform: 'uppercase',
            }}>
              <span style={{
                fontFamily: 'Fraunces', fontSize: 42, fontStyle: 'italic', fontWeight: 700,
                color: zinePalette.accent, lineHeight: 1,
              }}>№ {p.n}</span>
              <span>{p.tag}</span>
            </div>

            <div style={{ display: 'flex', alignItems: 'flex-start', gap: 24 }}>
              <div style={{ flexShrink: 0, marginTop: 4 }}>
                <HoverSpin deg={25}>
                  <ZShape type={p.shape} size={80} color={p.color}/>
                </HoverSpin>
              </div>
              <div style={{ flex: 1 }}>
                <h3 style={{
                  fontFamily: 'Fraunces', fontSize: 38, fontWeight: 700, fontStyle: 'italic',
                  margin: 0, color: zinePalette.inkOnPaper, lineHeight: 1, letterSpacing: '-0.02em',
                }}>
                  {p.title}
                </h3>
                <p style={{
                  fontSize: 14, color: zinePalette.inkOnPaper, lineHeight: 1.6, margin: '16px 0 0',
                  opacity: 0.85,
                }} dangerouslySetInnerHTML={{ __html: p.desc }}/>
              </div>
            </div>

            <div style={{
              marginTop: 24, paddingTop: 16, borderTop: `1px dashed ${zinePalette.inkOnPaper}`,
              display: 'flex', justifyContent: 'space-between', alignItems: 'center',
            }}>
              <span style={{
                fontFamily: 'Fraunces', fontStyle: 'italic', fontSize: 18, color: zinePalette.accent,
                fontWeight: 600,
              }}>
                read more &rarr;
              </span>
              <span style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 10, color: zinePalette.inkOnPaper, opacity: 0.5, letterSpacing: '0.2em' }}>
                CUT HERE ✂
              </span>
            </div>
          </article>
        ))}
      </div>
    </section>
  );
}

// ---------- Now section (draggable polaroids) ----------
function ZineNow() {
  const isMobile = useIsMobile();
  const polaroids = [
    { label: 'reading', text: '"Pachinko" by\nMin Jin Lee', x: 60, y: 60, rot: -5, color: zinePalette.blue },
    { label: 'listening', text: 'mitski\non repeat', x: 300, y: 40, rot: 4, color: zinePalette.mustard },
    { label: 'learning', text: 'how to make\ndecent focaccia', x: 540, y: 80, rot: -3, color: zinePalette.sage },
    { label: 'making', text: 'this site\n(hi!)', x: 780, y: 50, rot: 6, color: zinePalette.accent },
    { label: 'wanting', text: 'a quiet\nweekend', x: 180, y: 300, rot: 3, color: zinePalette.plum },
    { label: 'watching', text: 'studio ghibli,\nagain', x: 440, y: 320, rot: -6, color: zinePalette.blue },
    { label: 'craving', text: 'cold coffee\n& mangoes', x: 680, y: 310, rot: 5, color: zinePalette.accent },
  ];

  const [order, setOrder] = React.useState(polaroids.map((_, i) => i));
  const pick = (i) => setOrder((prev) => [...prev.filter((x) => x !== i), i]);

  return (
    <section id="now" style={{
      background: zinePalette.paper, color: zinePalette.inkOnPaper,
      padding: isMobile ? '60px 20px' : '100px 80px 60px', position: 'relative',
    }}>
      <div style={{
        display: 'flex', justifyContent: 'space-between', borderBottom: `1px solid ${zinePalette.inkOnPaper}`,
        paddingBottom: 12, marginBottom: isMobile ? 28 : 40, fontFamily: 'JetBrains Mono, monospace', fontSize: isMobile ? 9 : 11,
        letterSpacing: isMobile ? '0.1em' : '0.2em', textTransform: 'uppercase', opacity: 0.7, gap: 8,
      }}>
        <span>P.04 · THE NOW PAGE</span>
        {!isMobile && <span>&mdash; drag the polaroids &mdash;</span>}
        <span>UPDATED APR 22, 2026</span>
      </div>

      <div style={{ maxWidth: 1100, margin: '0 auto', marginBottom: 40 }}>
        <div style={{ fontFamily: 'Fraunces', fontSize: 22, fontStyle: 'italic', color: zinePalette.accent, marginBottom: 8 }}>
          what I&rsquo;m up to —
        </div>
        <h2 style={{
          fontFamily: 'Fraunces', fontSize: 'clamp(40px, 10vw, 80px)', fontWeight: 700, margin: 0,
          lineHeight: 0.95, letterSpacing: '-0.03em', color: zinePalette.inkOnPaper,
        }}>
          this week, <em style={{ fontStyle: 'italic', color: zinePalette.blue }}>actually</em>.
        </h2>
      </div>

      {isMobile ? (
        /* Mobile: static wrapped grid of polaroids — no dragging */
        <div style={{
          display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 20, maxWidth: 1100, margin: '0 auto',
          justifyItems: 'center',
        }}>
          {polaroids.map((p, i) => (
            <div key={i} style={{
              width: '100%', maxWidth: 170, background: '#fff', padding: 10, paddingBottom: 30,
              boxShadow: `0 8px 16px rgba(0,0,0,0.15)`, transform: `rotate(${p.rot * 0.5}deg)`,
            }}>
              <div style={{
                width: '100%', aspectRatio: '1', background: p.color,
                display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative', overflow: 'hidden',
              }}>
                <span style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 9, color: '#fff', letterSpacing: '0.2em', opacity: 0.6 }}>[ IMG ]</span>
                <Tape width={60} rotation={8} color="rgba(212, 168, 58, 0.5)" style={{ position: 'absolute', top: -4, right: 8 }}/>
              </div>
              <div style={{
                marginTop: 12, fontFamily: 'Fraunces', fontStyle: 'italic', fontSize: 14,
                color: zinePalette.inkOnPaper, textAlign: 'center', whiteSpace: 'pre-line', lineHeight: 1.3,
              }}>
                <div style={{ fontFamily: 'JetBrains Mono, monospace', fontStyle: 'normal', fontSize: 9, color: p.color, letterSpacing: '0.2em', textTransform: 'uppercase', marginBottom: 4 }}>{p.label}</div>
                {p.text}
              </div>
            </div>
          ))}
        </div>
      ) : (
      /* Draggable polaroid field */
      <div style={{
        position: 'relative', maxWidth: 1100, margin: '0 auto', height: 540,
        background: `repeating-linear-gradient(90deg, transparent, transparent 40px, rgba(26, 33, 66, 0.04) 40px, rgba(26, 33, 66, 0.04) 41px)`,
        border: `1px dashed ${zinePalette.inkOnPaper}`, borderRadius: 4,
      }}>
        <div style={{
          position: 'absolute', top: 12, left: 16, fontFamily: 'JetBrains Mono, monospace',
          fontSize: 10, color: zinePalette.inkOnPaper, opacity: 0.5, letterSpacing: '0.2em',
        }}>
          ✦ DRAG ME ✦
        </div>
        {polaroids.map((p, i) => (
          <ZDraggable key={i} initX={p.x} initY={p.y} rot={p.rot} onPick={() => pick(i)}>
            <div style={{
              width: 180, background: '#fff', padding: 10, paddingBottom: 36,
              boxShadow: `0 10px 20px rgba(0,0,0,0.15)`,
              zIndex: order.indexOf(i),
            }}>
              <div style={{
                width: '100%', aspectRatio: '1', background: p.color,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                position: 'relative', overflow: 'hidden',
              }}>
                <span style={{
                  fontFamily: 'JetBrains Mono, monospace', fontSize: 9, color: '#fff',
                  letterSpacing: '0.2em', opacity: 0.6,
                }}>
                  [ IMG ]
                </span>
                <Tape width={70} rotation={8} color="rgba(212, 168, 58, 0.5)" style={{
                  position: 'absolute', top: -4, right: 10,
                }}/>
              </div>
              <div style={{
                marginTop: 14, fontFamily: 'Fraunces', fontStyle: 'italic', fontSize: 15,
                color: zinePalette.inkOnPaper, textAlign: 'center', whiteSpace: 'pre-line', lineHeight: 1.3,
              }}>
                <div style={{
                  fontFamily: 'JetBrains Mono, monospace', fontStyle: 'normal', fontSize: 9,
                  color: p.color, letterSpacing: '0.2em', textTransform: 'uppercase', marginBottom: 4,
                }}>{p.label}</div>
                {p.text}
              </div>
            </div>
          </ZDraggable>
        ))}
      </div>
      )}
    </section>
  );
}

// ---------- Interests ----------
function ZineInterests() {
  const isMobile = useIsMobile();
  const items = [
    { n: 'i.', title: 'writing', desc: 'putting small thoughts into words. mostly lists. sometimes letters.', color: zinePalette.accent, icon: 'note' },
    { n: 'ii.', title: 'reading', desc: 'a good book on a quiet afternoon. or a loud one, honestly.', color: zinePalette.mustard, icon: 'eye' },
    { n: 'iii.', title: 'learning', desc: 'picking up something new each day. today: the word \u201cpetrichor\u201d.', color: zinePalette.sage, icon: 'star' },
    { n: 'iv.', title: 'creating', desc: 'making small things with big care. this site, for instance.', color: zinePalette.plum, icon: 'scissors' },
  ];

  return (
    <section id="interests" style={{
      background: zinePalette.bg, color: zinePalette.ink,
      padding: isMobile ? '60px 20px' : '100px 80px', position: 'relative',
    }}>
      <div style={{
        display: 'flex', justifyContent: 'space-between', borderBottom: `1px solid ${zinePalette.line}`,
        paddingBottom: 12, marginBottom: isMobile ? 36 : 60, fontFamily: 'JetBrains Mono, monospace', fontSize: isMobile ? 9 : 11,
        color: zinePalette.inkDim, letterSpacing: isMobile ? '0.1em' : '0.2em', textTransform: 'uppercase', gap: 8,
      }}>
        <span>P.05 · A FEW FAVOURITE THINGS</span>
        {!isMobile && <span>&mdash; in no particular order &mdash;</span>}
        <span>04 OF THEM</span>
      </div>

      <div style={{ maxWidth: 1100, margin: '0 auto 60px', textAlign: 'center' }}>
        <div style={{ fontFamily: 'Fraunces', fontSize: 22, fontStyle: 'italic', color: zinePalette.mustard, marginBottom: 8 }}>
          ∗ what I love ∗
        </div>
        <h2 style={{
          fontFamily: 'Fraunces', fontSize: 'clamp(44px, 11vw, 96px)', fontWeight: 700, margin: 0, lineHeight: 0.95,
          letterSpacing: '-0.03em',
        }}>
          little <em style={{ fontStyle: 'italic', color: zinePalette.sage }}>obsessions</em>.
        </h2>
      </div>

      <div style={{ maxWidth: 1100, margin: '0 auto', display: 'grid', gridTemplateColumns: isMobile ? '1fr 1fr' : 'repeat(4, 1fr)', gap: 0, border: `1px solid ${zinePalette.line}` }}>
        {items.map((it, i) => {
          const cols = isMobile ? 2 : 4;
          const hasRight = (i % cols) !== (cols - 1);
          const hasBottom = isMobile && i < items.length - cols;
          return (
          <div key={i} style={{
            padding: isMobile ? 24 : 32,
            borderRight: hasRight ? `1px solid ${zinePalette.line}` : 'none',
            borderBottom: hasBottom ? `1px solid ${zinePalette.line}` : 'none',
            transition: 'all 0.3s', position: 'relative', cursor: 'pointer', minHeight: isMobile ? 200 : 280,
          }}
          onMouseEnter={(e) => { e.currentTarget.style.background = it.color; }}
          onMouseLeave={(e) => { e.currentTarget.style.background = 'transparent'; }}>
            <div style={{
              fontFamily: 'Fraunces', fontSize: isMobile ? 44 : 60, fontStyle: 'italic', fontWeight: 700,
              color: it.color, lineHeight: 1, marginBottom: isMobile ? 14 : 20,
              transition: 'color 0.3s',
            }}>
              {it.n}
            </div>
            <div style={{ marginBottom: 16 }}>
              <HoverSpin deg={30}>
                <ZGlyph name={it.icon} size={isMobile ? 26 : 32} color={zinePalette.ink}/>
              </HoverSpin>
            </div>
            <h3 style={{
              fontFamily: 'Fraunces', fontSize: isMobile ? 24 : 32, fontStyle: 'italic', fontWeight: 700, margin: 0,
              letterSpacing: '-0.02em', marginBottom: 12, color: zinePalette.ink,
            }}>
              {it.title}
            </h3>
            <p style={{ fontSize: isMobile ? 13 : 14, color: zinePalette.inkDim, margin: 0, lineHeight: 1.6 }}>{it.desc}</p>
          </div>
          );
        })}
      </div>
    </section>
  );
}

// ---------- Footer ----------
function ZineFooter() {
  const isMobile = useIsMobile();
  return (
    <footer style={{
      background: zinePalette.accent, color: zinePalette.ink,
      padding: isMobile ? '56px 20px 28px' : '80px 80px 32px', position: 'relative',
    }}>
      <div style={{
        display: 'flex', justifyContent: 'space-between', borderBottom: `1px solid ${zinePalette.ink}`,
        paddingBottom: 12, marginBottom: isMobile ? 32 : 40, fontFamily: 'JetBrains Mono, monospace', fontSize: isMobile ? 9 : 11,
        letterSpacing: isMobile ? '0.1em' : '0.2em', textTransform: 'uppercase', gap: 8,
      }}>
        <span>BACK COVER · P.06</span>
        {!isMobile && <span>&mdash; thanks for flipping through &mdash;</span>}
        <span>TO BE CONTINUED</span>
      </div>

      <div style={{ maxWidth: 1100, margin: '0 auto' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', gap: isMobile ? 28 : 40, flexWrap: 'wrap' }}>
          <div>
            <div style={{
              fontFamily: 'Fraunces', fontSize: 'clamp(72px, 20vw, 160px)', fontWeight: 800, fontStyle: 'italic', lineHeight: 0.85,
              margin: 0, letterSpacing: '-0.05em',
            }}>
              say<br/><em style={{ color: zinePalette.ink, textDecoration: 'underline', textDecorationThickness: 6 }}>hello</em>.
            </div>
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12, minWidth: isMobile ? '100%' : 360, flex: isMobile ? '1 1 100%' : '0 1 auto' }}>
            {[
              { k: 'email', v: 'hello@vidya.dev' },
              { k: 'instagram', v: '@vid.draws' },
              { k: 'github', v: '@vidya' },
              { k: 'letterboxd', v: '@vidyawatches' },
            ].map((l) => (
              <a key={l.k} href="#" style={{
                display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                padding: '14px 20px', background: zinePalette.ink, color: zinePalette.accent,
                textDecoration: 'none', fontFamily: 'Fraunces', fontSize: 20, fontStyle: 'italic',
                fontWeight: 600, transition: 'all 0.2s',
                border: `2px solid ${zinePalette.ink}`,
              }}
              onMouseEnter={(e) => { e.currentTarget.style.background = zinePalette.accent; e.currentTarget.style.color = zinePalette.ink; }}
              onMouseLeave={(e) => { e.currentTarget.style.background = zinePalette.ink; e.currentTarget.style.color = zinePalette.accent; }}>
                <span style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 11, fontStyle: 'normal', letterSpacing: '0.2em', textTransform: 'uppercase' }}>{l.k}</span>
                {l.v} &rarr;
              </a>
            ))}
          </div>
        </div>

        <div style={{
          marginTop: isMobile ? 40 : 60, paddingTop: 20, borderTop: `1px solid ${zinePalette.ink}`,
          display: 'flex', justifyContent: 'space-between', flexWrap: 'wrap', gap: 8, fontFamily: 'JetBrains Mono, monospace',
          fontSize: isMobile ? 9 : 11, letterSpacing: isMobile ? '0.1em' : '0.15em',
        }}>
          <span>© 2026 VIDYA · ALL RIGHTS RESERVED (MOSTLY)</span>
          {!isMobile && <span>PRINTED IN HTML, CSS & A LITTLE JAVASCRIPT</span>}
          <span>ISSUE 01 · END</span>
        </div>
      </div>
    </footer>
  );
}

// ---------- Easter egg — same shape-burst as V1 but with zine shapes ----------
function ZEasterEgg({ containerRef }) {
  const [bursts, setBursts] = React.useState([]);
  const bufRef = React.useRef('');
  React.useEffect(() => {
    const onKey = (e) => {
      const t = e.target;
      if (t && (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA')) return;
      bufRef.current = (bufRef.current + (e.key || '')).slice(-10).toLowerCase();
      if (bufRef.current.includes('vidya')) {
        bufRef.current = '';
        trigger();
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);
  const trigger = () => {
    const cont = containerRef.current;
    if (!cont) return;
    const rect = cont.getBoundingClientRect();
    const cx = rect.width / 2;
    const cy = (cont.scrollTop || 0) + rect.height / 2;
    const colors = [zinePalette.accent, zinePalette.mustard, zinePalette.sage, zinePalette.plum, zinePalette.blue];
    const shapes = ['cut-star', 'riso-circle', 'cloud', 'half', 'arch'];
    const items = Array.from({ length: 28 }).map(() => ({
      id: Math.random(), x: cx, y: cy,
      dx: (Math.random() - 0.5) * 900, dy: (Math.random() - 0.5) * 700 - 100,
      rot: Math.random() * 720 - 360, shape: shapes[Math.floor(Math.random() * shapes.length)],
      color: colors[Math.floor(Math.random() * colors.length)], size: 30 + Math.random() * 70,
    }));
    setBursts((prev) => [...prev, ...items]);
    setTimeout(() => setBursts((prev) => prev.filter((b) => !items.find((n) => n.id === b.id))), 2400);
  };
  return (
    <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none', zIndex: 1000, overflow: 'hidden' }}>
      {bursts.map((b) => (
        <div key={b.id} style={{
          position: 'absolute', left: b.x, top: b.y,
          transform: `translate(-50%, -50%) translate(${b.dx}px, ${b.dy}px) rotate(${b.rot}deg)`,
          animation: 'zburst-fade 2.4s forwards',
        }}>
          <ZShape type={b.shape} size={b.size} color={b.color}/>
        </div>
      ))}
      <style>{`
        @keyframes zburst-fade {
          0% { opacity: 1; transform: translate(-50%, -50%) scale(0.3); }
          80% { opacity: 1; }
          100% { opacity: 0; }
        }
      `}</style>
    </div>
  );
}

// ---------- Root ----------
function ZineHomepage({ tweaks = {} }) {
  const containerRef = React.useRef(null);
  return (
    <div ref={containerRef} style={{
      width: '100%', minHeight: '100%', background: zinePalette.bg,
      color: zinePalette.ink, position: 'relative',
    }}>
      <ZEasterEgg containerRef={containerRef}/>
      <ZineHero tweaks={tweaks}/>
      <ZineAbout/>
      {tweaks.showMarquee !== false && <ZineMarquee/>}
      <ZineProjects/>
      <ZineNow/>
      <ZineInterests/>
      <ZineFooter/>
    </div>
  );
}

window.ZineHomepage = ZineHomepage;
