// pipi-scribble.jsx — Scribble SVG primitives + Pipi character set
// Style: "bad MS Paint mouse-drawn redraw" — wobbly outlines, flat fills,
// scribbly hatching, intentionally off proportions.

const PIPI = {
  // Paper / surfaces
  paper:   '#F5E7C7',     // warm cream (background of every illustration)
  paperLt: '#FBF1D9',     // lighter cream (card surfaces)
  paperDk: '#E8D7AE',     // dustier cream (recessed)
  // Ink
  ink:     '#1A1A2E',     // near-black outline
  inkSoft: '#3A3A52',     // softer outline
  // Hero colors (flat, MS-Paint primary feel)
  yellow:  '#FFD93D',     // Pipi feathers
  yellowD: '#E5B82E',     // Pipi shading
  pink:    '#E8526B',     // berry
  pinkLt:  '#F4A6B0',     // cheeks
  blue:    '#6FA8DC',     // sky
  blueD:   '#3F7CB8',     // deep
  green:   '#6EB76A',     // leaf
  greenD:  '#3F8A4F',     // darker leaf
  lilac:   '#B79DD9',     // magic
  coral:   '#F2A65A',     // beak
  red:     '#C84B3A',     // accent
};

// Deterministic 0..1 noise for jitter (seeded so renders are stable)
function pjit(seed, i) {
  const v = Math.sin(seed * 9301.137 + i * 4937.71) * 43758.5453;
  return (v - Math.floor(v)) - 0.5; // -0.5..0.5
}

// Build a wobbly closed polygon from a list of base points.
// amp = jitter amplitude in px; resolution = subdivide each edge by N
function wobblyPath(points, { amp = 2.5, seed = 1, res = 1, close = true } = {}) {
  const pts = [];
  for (let i = 0; i < points.length; i++) {
    const a = points[i];
    const b = points[(i + 1) % points.length];
    for (let s = 0; s < res; s++) {
      const t = s / res;
      const x = a[0] + (b[0] - a[0]) * t;
      const y = a[1] + (b[1] - a[1]) * t;
      pts.push([
        x + pjit(seed, pts.length * 2) * amp,
        y + pjit(seed, pts.length * 2 + 1) * amp,
      ]);
    }
    if (!close && i === points.length - 1) {
      pts.push([b[0] + pjit(seed, pts.length * 2) * amp,
                b[1] + pjit(seed, pts.length * 2 + 1) * amp]);
    }
  }
  let d = `M${pts[0][0].toFixed(1)} ${pts[0][1].toFixed(1)}`;
  for (let i = 1; i < pts.length; i++) d += ` L${pts[i][0].toFixed(1)} ${pts[i][1].toFixed(1)}`;
  if (close) d += ' Z';
  return d;
}

function wobblyRectPath(x, y, w, h, { r = 18, amp = 2.5, seed = 1, res = 6 } = {}) {
  // 8 corner-stops around a rounded rect, then jittered along edges
  const pts = [];
  // top edge L→R
  for (let i = 0; i <= res; i++) pts.push([x + r + (w - 2 * r) * (i / res), y]);
  // right rounded corner
  for (let i = 1; i <= res / 2; i++) {
    const a = -Math.PI / 2 + (Math.PI / 2) * (i / (res / 2));
    pts.push([x + w - r + Math.cos(a) * r, y + r + Math.sin(a) * r]);
  }
  // right edge
  for (let i = 1; i <= res; i++) pts.push([x + w, y + r + (h - 2 * r) * (i / res)]);
  // br corner
  for (let i = 1; i <= res / 2; i++) {
    const a = 0 + (Math.PI / 2) * (i / (res / 2));
    pts.push([x + w - r + Math.cos(a) * r, y + h - r + Math.sin(a) * r]);
  }
  // bottom edge R→L
  for (let i = 1; i <= res; i++) pts.push([x + w - r - (w - 2 * r) * (i / res), y + h]);
  // bl corner
  for (let i = 1; i <= res / 2; i++) {
    const a = Math.PI / 2 + (Math.PI / 2) * (i / (res / 2));
    pts.push([x + r + Math.cos(a) * r, y + h - r + Math.sin(a) * r]);
  }
  // left edge
  for (let i = 1; i <= res; i++) pts.push([x, y + h - r - (h - 2 * r) * (i / res)]);
  // tl corner
  for (let i = 1; i <= res / 2; i++) {
    const a = Math.PI + (Math.PI / 2) * (i / (res / 2));
    pts.push([x + r + Math.cos(a) * r, y + r + Math.sin(a) * r]);
  }
  return wobblyPath(pts, { amp, seed, res: 1 });
}

function wobblyCirclePath(cx, cy, r, { amp = 2, seed = 1, segs = 24 } = {}) {
  const pts = [];
  for (let i = 0; i < segs; i++) {
    const a = (i / segs) * Math.PI * 2;
    pts.push([cx + Math.cos(a) * r, cy + Math.sin(a) * r]);
  }
  return wobblyPath(pts, { amp, seed, res: 1 });
}

function wobblyLinePath(x1, y1, x2, y2, { amp = 1.8, seed = 1, segs = 8 } = {}) {
  let d = '';
  for (let i = 0; i <= segs; i++) {
    const t = i / segs;
    const x = x1 + (x2 - x1) * t + pjit(seed, i * 2) * amp;
    const y = y1 + (y2 - y1) * t + pjit(seed, i * 2 + 1) * amp;
    d += (i === 0 ? 'M' : 'L') + x.toFixed(1) + ' ' + y.toFixed(1);
  }
  return d;
}

// Scribble fill — a back-and-forth wobbly zigzag, used for hair, ground, fur
function scribblePath(x, y, w, h, { angle = -0.5, gap = 6, amp = 2, seed = 1 } = {}) {
  const lines = Math.ceil(h / gap);
  let d = '';
  for (let i = 0; i < lines; i++) {
    const yy = y + i * gap;
    const ltr = i % 2 === 0;
    const x1 = ltr ? x : x + w;
    const x2 = ltr ? x + w : x;
    const segs = 6;
    for (let s = 0; s <= segs; s++) {
      const t = s / segs;
      const xx = x1 + (x2 - x1) * t + pjit(seed, i * 13 + s) * amp;
      const yyy = yy + Math.tan(angle) * (xx - x) + pjit(seed, i * 13 + s + 100) * amp;
      d += (s === 0 && i === 0 ? 'M' : (s === 0 ? 'L' : 'L')) + xx.toFixed(1) + ' ' + yyy.toFixed(1);
    }
  }
  return d;
}

// ── Components ────────────────────────────────────────────────

// Wobbly box, used everywhere as cards/buttons. Offsets a duplicate outline
// behind it for a "MS Paint misregister" look.
function ScribbleBox({ x = 0, y = 0, w = 100, h = 60, r = 18, fill = PIPI.paperLt,
                       stroke = PIPI.ink, sw = 3.5, seed = 1, amp = 2,
                       offset = false, offsetColor = PIPI.ink, children }) {
  const d = wobblyRectPath(x, y, w, h, { r, amp, seed });
  return (
    <g>
      {offset && (
        <path d={wobblyRectPath(x + 2.5, y + 3, w, h, { r, amp: amp * 1.1, seed: seed + 99 })}
              fill="none" stroke={offsetColor} strokeWidth={sw * 0.7} strokeLinejoin="round"
              strokeLinecap="round" opacity={0.35}/>
      )}
      <path d={d} fill={fill} stroke={stroke} strokeWidth={sw}
            strokeLinejoin="round" strokeLinecap="round"/>
      {children}
    </g>
  );
}

function ScribbleCircle({ cx, cy, r, fill = PIPI.yellow, stroke = PIPI.ink, sw = 3.5,
                          amp = 2, seed = 1, segs = 24 }) {
  return (
    <path d={wobblyCirclePath(cx, cy, r, { amp, seed, segs })}
          fill={fill} stroke={stroke} strokeWidth={sw}
          strokeLinejoin="round" strokeLinecap="round"/>
  );
}

function ScribbleLine({ x1, y1, x2, y2, stroke = PIPI.ink, sw = 3, amp = 1.8, seed = 1, segs = 8 }) {
  return (
    <path d={wobblyLinePath(x1, y1, x2, y2, { amp, seed, segs })}
          fill="none" stroke={stroke} strokeWidth={sw}
          strokeLinejoin="round" strokeLinecap="round"/>
  );
}

// Scribble fill (zigzag hatching) — clipped to an arbitrary path id
function ScribbleFill({ clipId, x, y, w, h, angle = -0.5, gap = 6, amp = 2, seed = 1,
                        stroke = PIPI.ink, sw = 1.8, opacity = 1 }) {
  return (
    <g clipPath={`url(#${clipId})`}>
      <path d={scribblePath(x, y, w, h, { angle, gap, amp, seed })}
            fill="none" stroke={stroke} strokeWidth={sw}
            strokeLinejoin="round" strokeLinecap="round" opacity={opacity}/>
    </g>
  );
}

// ── PIPI character — a little fluffy yellow chick ────────────
// All positions are in a 200x200 viewBox area, callable at any size.
function Pipi({ size = 200, mood = 'happy', seed = 7 }) {
  const s = seed;
  // Body
  const bodyD = wobblyCirclePath(100, 120, 56, { amp: 3, seed: s, segs: 28 });
  // Head (slightly elliptical, wobbly)
  const headPts = [];
  for (let i = 0; i < 28; i++) {
    const a = (i / 28) * Math.PI * 2;
    headPts.push([100 + Math.cos(a) * 46, 70 + Math.sin(a) * 42]);
  }
  const headD = wobblyPath(headPts, { amp: 3, seed: s + 1 });
  // Tuft (3 little scribble strands)
  const tuftD =
    `M${85},${30} L${82},${14} L${90},${22} L${94},${10} L${100},${22} L${108},${12} L${112},${24} L${120},${18} L${118},${30}`;
  // Beak
  const beakD = `M${88},${74} L${72},${82} L${88},${88} Z`;
  // Cheeks
  // Eyes — googly, slightly different sizes (MS Paint feel)
  const eyeLx = 86, eyeLy = 64, eyeRx = 118, eyeRy = 66;
  // Wing
  const wingD = wobblyPath([
    [54, 116], [40, 130], [50, 150], [70, 154], [78, 140], [72, 122]
  ], { amp: 2.5, seed: s + 5 });
  // Feet
  return (
    <svg viewBox="0 0 200 200" width={size} height={size} aria-hidden="true" style={{ display: 'block' }}>
      {/* Feet — drawn first so body covers their tops */}
      <path d={wobblyLinePath(85, 175, 78, 188, { amp: 1.5, seed: s + 20, segs: 4 })}
            fill="none" stroke={PIPI.ink} strokeWidth={4} strokeLinecap="round"/>
      <path d={wobblyLinePath(85, 188, 72, 188, { amp: 1.2, seed: s + 21, segs: 3 })}
            fill="none" stroke={PIPI.ink} strokeWidth={4} strokeLinecap="round"/>
      <path d={wobblyLinePath(85, 188, 80, 192, { amp: 1.2, seed: s + 22, segs: 3 })}
            fill="none" stroke={PIPI.ink} strokeWidth={4} strokeLinecap="round"/>
      <path d={wobblyLinePath(115, 175, 122, 188, { amp: 1.5, seed: s + 23, segs: 4 })}
            fill="none" stroke={PIPI.ink} strokeWidth={4} strokeLinecap="round"/>
      <path d={wobblyLinePath(115, 188, 128, 188, { amp: 1.2, seed: s + 24, segs: 3 })}
            fill="none" stroke={PIPI.ink} strokeWidth={4} strokeLinecap="round"/>
      <path d={wobblyLinePath(115, 188, 120, 192, { amp: 1.2, seed: s + 25, segs: 3 })}
            fill="none" stroke={PIPI.ink} strokeWidth={4} strokeLinecap="round"/>

      {/* Body */}
      <path d={bodyD} fill={PIPI.yellow} stroke={PIPI.ink} strokeWidth={4}
            strokeLinejoin="round" strokeLinecap="round"/>
      {/* Belly shading scribble */}
      <defs>
        <clipPath id={`pipi-body-${s}`}><path d={bodyD}/></clipPath>
      </defs>
      <g clipPath={`url(#pipi-body-${s})`}>
        <path d={scribblePath(80, 140, 50, 28, { gap: 5, amp: 1.5, seed: s + 30 })}
              fill="none" stroke={PIPI.yellowD} strokeWidth={1.8} strokeLinecap="round"/>
      </g>
      {/* Wing */}
      <path d={wingD} fill={PIPI.yellowD} stroke={PIPI.ink} strokeWidth={4}
            strokeLinejoin="round" strokeLinecap="round"/>

      {/* Head */}
      <path d={headD} fill={PIPI.yellow} stroke={PIPI.ink} strokeWidth={4}
            strokeLinejoin="round" strokeLinecap="round"/>

      {/* Tuft */}
      <path d={tuftD} fill="none" stroke={PIPI.ink} strokeWidth={4}
            strokeLinejoin="round" strokeLinecap="round"/>

      {/* Cheeks */}
      <path d={wobblyCirclePath(72, 78, 7, { amp: 1, seed: s + 40, segs: 14 })}
            fill={PIPI.pinkLt} stroke="none"/>
      <path d={wobblyCirclePath(130, 80, 7, { amp: 1, seed: s + 41, segs: 14 })}
            fill={PIPI.pinkLt} stroke="none"/>

      {/* Eyes — whites */}
      <path d={wobblyCirclePath(eyeLx, eyeLy, 10, { amp: 1.2, seed: s + 50, segs: 16 })}
            fill="#fff" stroke={PIPI.ink} strokeWidth={3}/>
      <path d={wobblyCirclePath(eyeRx, eyeRy, 11, { amp: 1.2, seed: s + 51, segs: 16 })}
            fill="#fff" stroke={PIPI.ink} strokeWidth={3}/>
      {/* Pupils */}
      {mood === 'asleep' ? (
        <>
          <path d={wobblyLinePath(eyeLx - 6, eyeLy, eyeLx + 6, eyeLy, { amp: 0.8, seed: s + 60, segs: 4 })}
                fill="none" stroke={PIPI.ink} strokeWidth={3.5} strokeLinecap="round"/>
          <path d={wobblyLinePath(eyeRx - 6, eyeRy, eyeRx + 6, eyeRy, { amp: 0.8, seed: s + 61, segs: 4 })}
                fill="none" stroke={PIPI.ink} strokeWidth={3.5} strokeLinecap="round"/>
        </>
      ) : (
        <>
          <ellipse cx={eyeLx + 1} cy={eyeLy + 1} rx="3.5" ry="4" fill={PIPI.ink}/>
          <ellipse cx={eyeRx + 1} cy={eyeRy + 1} rx="3.5" ry="4" fill={PIPI.ink}/>
          <ellipse cx={eyeLx + 2.5} cy={eyeLy - 1} rx="1.2" ry="1.4" fill="#fff"/>
          <ellipse cx={eyeRx + 2.5} cy={eyeRy - 1} rx="1.2" ry="1.4" fill="#fff"/>
        </>
      )}

      {/* Beak */}
      <path d={beakD} fill={PIPI.coral} stroke={PIPI.ink} strokeWidth={3.5}
            strokeLinejoin="round"/>
      <path d={wobblyLinePath(74, 82, 88, 82, { amp: 0.6, seed: s + 70, segs: 4 })}
            fill="none" stroke={PIPI.ink} strokeWidth={2}/>
    </svg>
  );
}

// Smaller chibi Pipi head only (for nav icons, mini avatars)
function PipiMini({ size = 60, seed = 11 }) {
  return (
    <svg viewBox="0 0 100 100" width={size} height={size} aria-hidden="true" style={{ display: 'block' }}>
      <path d={wobblyCirclePath(50, 52, 38, { amp: 2, seed, segs: 22 })}
            fill={PIPI.yellow} stroke={PIPI.ink} strokeWidth={3.5}
            strokeLinejoin="round" strokeLinecap="round"/>
      <path d="M44 18 L42 8 L48 14 L52 6 L56 16 L62 10 L60 20"
            fill="none" stroke={PIPI.ink} strokeWidth={3.2} strokeLinecap="round"/>
      <path d={wobblyCirclePath(40, 48, 6, { amp: 0.8, seed: seed + 5, segs: 12 })}
            fill="#fff" stroke={PIPI.ink} strokeWidth={2.5}/>
      <path d={wobblyCirclePath(62, 48, 6, { amp: 0.8, seed: seed + 6, segs: 12 })}
            fill="#fff" stroke={PIPI.ink} strokeWidth={2.5}/>
      <ellipse cx="41" cy="49" rx="2.2" ry="2.6" fill={PIPI.ink}/>
      <ellipse cx="63" cy="49" rx="2.2" ry="2.6" fill={PIPI.ink}/>
      <path d="M44 60 L34 66 L44 71 Z" fill={PIPI.coral} stroke={PIPI.ink} strokeWidth={2.5} strokeLinejoin="round"/>
      <path d={wobblyCirclePath(28, 60, 4, { amp: 0.6, seed: seed + 7, segs: 10 })}
            fill={PIPI.pinkLt} stroke="none"/>
      <path d={wobblyCirclePath(74, 62, 4, { amp: 0.6, seed: seed + 8, segs: 10 })}
            fill={PIPI.pinkLt} stroke="none"/>
    </svg>
  );
}

// ── Story illustration placeholders (the MS-Paint redraws) ────
// Each story has its own goofy scribbly cover art.

function StoryFairy({ size = 220, seed = 3 }) {
  return (
    <svg viewBox="0 0 240 240" width={size} height={size} aria-hidden="true" style={{ display: 'block' }}>
      {/* Sky-ish backdrop scribble */}
      <path d={scribblePath(10, 10, 220, 220, { gap: 14, amp: 2.5, seed, angle: -0.3 })}
            fill="none" stroke={PIPI.lilac} strokeWidth={1.4} opacity={0.5}/>
      {/* Mushroom house */}
      <path d={wobblyPath([[40,200],[40,160],[60,140],[100,140],[120,160],[120,200]], { amp: 2, seed: seed + 1 })}
            fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={3.5}/>
      <path d={wobblyPath([[30,158],[60,110],[100,110],[130,158]], { amp: 3, seed: seed + 2 })}
            fill={PIPI.red} stroke={PIPI.ink} strokeWidth={3.5}/>
      <circle cx="50" cy="135" r="6" fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={2}/>
      <circle cx="80" cy="125" r="5" fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={2}/>
      <circle cx="105" cy="138" r="4" fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={2}/>
      <path d={wobblyRectPath(70, 168, 22, 30, { r: 11, amp: 1.5, seed: seed + 3 })}
            fill={PIPI.ink} stroke={PIPI.ink} strokeWidth={2}/>
      {/* Fairy */}
      <path d={wobblyCirclePath(170, 90, 18, { amp: 2, seed: seed + 10, segs: 16 })}
            fill={PIPI.pinkLt} stroke={PIPI.ink} strokeWidth={3}/>
      <ellipse cx="166" cy="88" rx="2" ry="2.5" fill={PIPI.ink}/>
      <ellipse cx="175" cy="88" rx="2" ry="2.5" fill={PIPI.ink}/>
      <path d="M165 96 Q170 99 175 96" fill="none" stroke={PIPI.ink} strokeWidth={2.5} strokeLinecap="round"/>
      {/* Wings */}
      <path d={wobblyPath([[155,80],[135,60],[140,90],[155,95]], { amp: 2, seed: seed + 11 })}
            fill={PIPI.blue} stroke={PIPI.ink} strokeWidth={2.5} opacity={0.85}/>
      <path d={wobblyPath([[185,80],[205,62],[200,92],[185,95]], { amp: 2, seed: seed + 12 })}
            fill={PIPI.blue} stroke={PIPI.ink} strokeWidth={2.5} opacity={0.85}/>
      {/* Body / dress */}
      <path d={wobblyPath([[160,108],[150,160],[190,160],[180,108]], { amp: 2, seed: seed + 13 })}
            fill={PIPI.pink} stroke={PIPI.ink} strokeWidth={3}/>
      {/* Wand */}
      <path d={wobblyLinePath(190, 130, 215, 105, { amp: 1, seed: seed + 14, segs: 5 })}
            fill="none" stroke={PIPI.ink} strokeWidth={3}/>
      <path d="M215 95 L218 102 L225 102 L219 107 L221 114 L215 110 L209 114 L211 107 L205 102 L212 102 Z"
            fill={PIPI.yellow} stroke={PIPI.ink} strokeWidth={2}/>
      {/* Sparkles */}
      {[[50,40,seed+20],[200,40,seed+21],[20,90,seed+22],[220,160,seed+23]].map(([x,y,sd],i) => (
        <g key={i}>
          <path d={`M${x} ${y-6} L${x+1} ${y-1} L${x+6} ${y} L${x+1} ${y+1} L${x} ${y+6} L${x-1} ${y+1} L${x-6} ${y} L${x-1} ${y-1} Z`}
                fill={PIPI.yellow} stroke={PIPI.ink} strokeWidth={1.5}/>
        </g>
      ))}
    </svg>
  );
}

function StoryMoon({ size = 220, seed = 5 }) {
  return (
    <svg viewBox="0 0 240 240" width={size} height={size} aria-hidden="true" style={{ display: 'block' }}>
      <path d={scribblePath(10, 10, 220, 220, { gap: 16, amp: 2, seed, angle: 0.4 })}
            fill="none" stroke={PIPI.blueD} strokeWidth={1.2} opacity={0.45}/>
      {/* Moon */}
      <path d={wobblyCirclePath(120, 100, 60, { amp: 3, seed: seed + 1, segs: 28 })}
            fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={4}/>
      {/* Moon face */}
      <ellipse cx="100" cy="95" rx="4" ry="6" fill={PIPI.ink}/>
      <ellipse cx="140" cy="95" rx="4" ry="6" fill={PIPI.ink}/>
      <path d={wobblyLinePath(95, 120, 145, 120, { amp: 2, seed: seed + 10, segs: 8 })}
            fill="none" stroke={PIPI.ink} strokeWidth={3.5} strokeLinecap="round"/>
      <path d={wobblyCirclePath(85, 110, 6, { amp: 0.6, seed: seed + 11, segs: 10 })}
            fill={PIPI.pinkLt} stroke="none"/>
      <path d={wobblyCirclePath(155, 110, 6, { amp: 0.6, seed: seed + 12, segs: 10 })}
            fill={PIPI.pinkLt} stroke="none"/>
      {/* Z's */}
      <text x="180" y="60" fontFamily="Caveat" fontSize="32" fill={PIPI.ink} transform="rotate(8 180 60)">Z</text>
      <text x="200" y="80" fontFamily="Caveat" fontSize="22" fill={PIPI.ink} transform="rotate(8 200 80)">z</text>
      {/* Stars */}
      {[[40,50],[200,40],[20,180],[210,200],[50,210]].map(([x,y],i) => (
        <path key={i}
          d={`M${x} ${y-5} L${x+2} ${y-1} L${x+6} ${y} L${x+2} ${y+1} L${x} ${y+5} L${x-2} ${y+1} L${x-6} ${y} L${x-2} ${y-1} Z`}
          fill={PIPI.yellow} stroke={PIPI.ink} strokeWidth={1.5}/>
      ))}
    </svg>
  );
}

function StoryDragon({ size = 220, seed = 9 }) {
  return (
    <svg viewBox="0 0 240 240" width={size} height={size} aria-hidden="true" style={{ display: 'block' }}>
      <path d={scribblePath(10, 10, 220, 220, { gap: 16, amp: 2, seed, angle: 0.2 })}
            fill="none" stroke={PIPI.green} strokeWidth={1.2} opacity={0.4}/>
      {/* Dragon body */}
      <path d={wobblyPath([
        [60,160],[40,140],[40,110],[70,90],[110,80],[150,90],[180,120],[180,160],[160,180],[80,180]
      ], { amp: 3, seed: seed + 1 })}
            fill={PIPI.green} stroke={PIPI.ink} strokeWidth={4}/>
      {/* Belly */}
      <path d={wobblyPath([[80,160],[100,175],[150,175],[170,160],[170,150],[80,150]], { amp: 2, seed: seed + 2 })}
            fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={3}/>
      {/* Spikes */}
      {[[80,80],[110,72],[140,75],[165,90]].map(([x,y],i) => (
        <path key={i} d={`M${x-8} ${y+8} L${x} ${y-10} L${x+8} ${y+8} Z`}
              fill={PIPI.greenD} stroke={PIPI.ink} strokeWidth={2.5} strokeLinejoin="round"/>
      ))}
      {/* Eye */}
      <path d={wobblyCirclePath(150, 110, 9, { amp: 1, seed: seed + 5, segs: 12 })}
            fill="#fff" stroke={PIPI.ink} strokeWidth={3}/>
      <ellipse cx="152" cy="111" rx="3" ry="4" fill={PIPI.ink}/>
      {/* Nostril */}
      <circle cx="178" cy="125" r="2.5" fill={PIPI.ink}/>
      {/* Smoke puffs */}
      <path d={wobblyCirclePath(200, 100, 10, { amp: 1.5, seed: seed + 10, segs: 14 })}
            fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={2.5}/>
      <path d={wobblyCirclePath(215, 80, 8, { amp: 1.2, seed: seed + 11, segs: 12 })}
            fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={2.5}/>
      <path d={wobblyCirclePath(225, 60, 6, { amp: 1, seed: seed + 12, segs: 10 })}
            fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={2}/>
    </svg>
  );
}

function StorySea({ size = 220, seed = 13 }) {
  return (
    <svg viewBox="0 0 240 240" width={size} height={size} aria-hidden="true" style={{ display: 'block' }}>
      {/* water scribble */}
      <path d={scribblePath(0, 90, 240, 150, { gap: 10, amp: 2.5, seed, angle: 0.1 })}
            fill="none" stroke={PIPI.blue} strokeWidth={1.6} opacity={0.8}/>
      <path d={wobblyLinePath(0, 90, 240, 90, { amp: 4, seed: seed + 1, segs: 18 })}
            fill="none" stroke={PIPI.ink} strokeWidth={3.5}/>
      {/* Fish */}
      <path d={wobblyPath([[80,140],[130,120],[160,140],[130,160]], { amp: 2, seed: seed + 2 })}
            fill={PIPI.coral} stroke={PIPI.ink} strokeWidth={3.5}/>
      <path d={wobblyPath([[160,140],[180,125],[180,155]], { amp: 2, seed: seed + 3 })}
            fill={PIPI.coral} stroke={PIPI.ink} strokeWidth={3.5}/>
      <circle cx="100" cy="135" r="5" fill="#fff" stroke={PIPI.ink} strokeWidth={2}/>
      <circle cx="100" cy="136" r="2.2" fill={PIPI.ink}/>
      {/* Bubbles */}
      <circle cx="60" cy="110" r="6" fill="none" stroke={PIPI.ink} strokeWidth={2.5}/>
      <circle cx="50" cy="95" r="4" fill="none" stroke={PIPI.ink} strokeWidth={2}/>
      <circle cx="200" cy="100" r="5" fill="none" stroke={PIPI.ink} strokeWidth={2.5}/>
      {/* Sun */}
      <path d={wobblyCirclePath(40, 40, 18, { amp: 1.5, seed: seed + 8, segs: 16 })}
            fill={PIPI.yellow} stroke={PIPI.ink} strokeWidth={3}/>
      {[0,45,90,135,180,225,270,315].map(a => {
        const r = a * Math.PI / 180;
        const x1 = 40 + Math.cos(r) * 22, y1 = 40 + Math.sin(r) * 22;
        const x2 = 40 + Math.cos(r) * 30, y2 = 40 + Math.sin(r) * 30;
        return <line key={a} x1={x1} y1={y1} x2={x2} y2={y2} stroke={PIPI.ink} strokeWidth={2.5} strokeLinecap="round"/>;
      })}
    </svg>
  );
}

function StoryRobot({ size = 220, seed = 17 }) {
  return (
    <svg viewBox="0 0 240 240" width={size} height={size} aria-hidden="true" style={{ display: 'block' }}>
      <path d={scribblePath(10, 10, 220, 220, { gap: 18, amp: 2, seed, angle: -0.2 })}
            fill="none" stroke={PIPI.lilac} strokeWidth={1.2} opacity={0.4}/>
      {/* Body */}
      <path d={wobblyRectPath(70, 90, 100, 110, { r: 12, amp: 2.5, seed: seed + 1 })}
            fill={PIPI.lilac} stroke={PIPI.ink} strokeWidth={4}/>
      {/* Head */}
      <path d={wobblyRectPath(80, 30, 80, 70, { r: 10, amp: 2.5, seed: seed + 2 })}
            fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={4}/>
      {/* Antenna */}
      <path d={wobblyLinePath(120, 30, 120, 10, { amp: 1, seed: seed + 3, segs: 4 })}
            fill="none" stroke={PIPI.ink} strokeWidth={3}/>
      <circle cx="120" cy="8" r="5" fill={PIPI.red} stroke={PIPI.ink} strokeWidth={2.5}/>
      {/* Eyes */}
      <path d={wobblyCirclePath(100, 60, 8, { amp: 1, seed: seed + 4, segs: 12 })}
            fill={PIPI.blue} stroke={PIPI.ink} strokeWidth={3}/>
      <path d={wobblyCirclePath(140, 60, 8, { amp: 1, seed: seed + 5, segs: 12 })}
            fill={PIPI.blue} stroke={PIPI.ink} strokeWidth={3}/>
      {/* Mouth (grid) */}
      <path d={wobblyRectPath(95, 80, 50, 14, { r: 4, amp: 1, seed: seed + 6 })}
            fill={PIPI.ink} stroke={PIPI.ink} strokeWidth={2}/>
      <line x1="105" y1="80" x2="105" y2="94" stroke={PIPI.paperLt} strokeWidth={2}/>
      <line x1="115" y1="80" x2="115" y2="94" stroke={PIPI.paperLt} strokeWidth={2}/>
      <line x1="125" y1="80" x2="125" y2="94" stroke={PIPI.paperLt} strokeWidth={2}/>
      <line x1="135" y1="80" x2="135" y2="94" stroke={PIPI.paperLt} strokeWidth={2}/>
      {/* Chest button */}
      <circle cx="120" cy="140" r="10" fill={PIPI.yellow} stroke={PIPI.ink} strokeWidth={3}/>
      <path d="M115 140 L119 144 L126 136" fill="none" stroke={PIPI.ink} strokeWidth={2.5} strokeLinecap="round" strokeLinejoin="round"/>
      {/* Arms */}
      <path d={wobblyLinePath(70, 130, 40, 150, { amp: 1.5, seed: seed + 7, segs: 5 })}
            fill="none" stroke={PIPI.ink} strokeWidth={4} strokeLinecap="round"/>
      <path d={wobblyLinePath(170, 130, 200, 150, { amp: 1.5, seed: seed + 8, segs: 5 })}
            fill="none" stroke={PIPI.ink} strokeWidth={4} strokeLinecap="round"/>
      <circle cx="40" cy="150" r="7" fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={3}/>
      <circle cx="200" cy="150" r="7" fill={PIPI.paperLt} stroke={PIPI.ink} strokeWidth={3}/>
    </svg>
  );
}

// ── Wordmark "Pipi" ───────────────────────────────────────────
// Hand-drawn-feel letters, intentionally lopsided
function PipiWordmark({ height = 80, color = PIPI.ink, fill = PIPI.yellow }) {
  // Letters are drawn manually with wobbly strokes
  return (
    <svg viewBox="0 0 440 100" height={height} aria-hidden="true" style={{ display: 'block', overflow: 'visible' }}>
      {/* shadow / offset register */}
      <text x="9" y="78" fontFamily="Caveat, cursive" fontSize="92" fontWeight="700"
            fill="none" stroke={PIPI.ink} strokeWidth={2} opacity={0.25}
            transform="rotate(-2 220 60)">Ippy</text>
      {/* main fill */}
      <text x="6" y="76" fontFamily="Caveat, cursive" fontSize="92" fontWeight="700"
            fill={fill} stroke={color} strokeWidth={4} strokeLinejoin="round"
            paintOrder="stroke" transform="rotate(-2 220 60)">Ippy</text>
      {/* exclamation dot doodle */}
      <path d={wobblyCirclePath(412, 30, 7, { amp: 1.2, seed: 3, segs: 12 })}
            fill={PIPI.red} stroke={PIPI.ink} strokeWidth={3}/>
      {/* little doodle star next to it */}
      <path d="M430 60 L433 67 L440 68 L435 73 L436 80 L430 76 L424 80 L425 73 L420 68 L427 67 Z"
            fill={PIPI.coral} stroke={PIPI.ink} strokeWidth={2.5} strokeLinejoin="round"/>
    </svg>
  );
}

// ── Other tiny scribbles ──────────────────────────────────────
function Cloud({ size = 80, seed = 1, fill = '#fff' }) {
  return (
    <svg viewBox="0 0 100 60" width={size} aria-hidden="true" style={{ display: 'block' }}>
      <path d={wobblyPath([
        [10,40],[8,30],[18,22],[30,22],[36,14],[52,14],[62,22],[78,22],[88,32],[86,42],[78,48],[16,48]
      ], { amp: 2, seed })}
            fill={fill} stroke={PIPI.ink} strokeWidth={3.5}
            strokeLinejoin="round" strokeLinecap="round"/>
    </svg>
  );
}

function Heart({ size = 24, fill = PIPI.pink, seed = 1 }) {
  return (
    <svg viewBox="0 0 32 32" width={size} height={size} aria-hidden="true" style={{ display: 'block' }}>
      <path d={wobblyPath([
        [16,28],[4,16],[4,10],[10,6],[16,10],[22,6],[28,10],[28,16]
      ], { amp: 1.2, seed })}
            fill={fill} stroke={PIPI.ink} strokeWidth={3}
            strokeLinejoin="round"/>
    </svg>
  );
}

function Sparkle({ size = 24, seed = 1, fill = PIPI.yellow }) {
  const r1 = 12, r2 = 4;
  return (
    <svg viewBox="0 0 32 32" width={size} height={size} aria-hidden="true" style={{ display: 'block' }}>
      <path d={`M16 ${16-r1} L${16+r2} ${16-r2} L${16+r1} 16 L${16+r2} ${16+r2} L16 ${16+r1} L${16-r2} ${16+r2} L${16-r1} 16 L${16-r2} ${16-r2} Z`}
            fill={fill} stroke={PIPI.ink} strokeWidth={2.2} strokeLinejoin="round"/>
    </svg>
  );
}

// Squiggle underline doodle
function Squiggle({ width = 80, color = PIPI.ink, seed = 1 }) {
  let d = 'M0 5';
  const segs = 10;
  for (let i = 1; i <= segs; i++) {
    const x = (i / segs) * width;
    const y = 5 + Math.sin(i * 1.5 + seed) * 4 + pjit(seed, i) * 2;
    d += ` L${x.toFixed(1)} ${y.toFixed(1)}`;
  }
  return (
    <svg width={width} height="12" aria-hidden="true" style={{ display: 'block' }}>
      <path d={d} fill="none" stroke={color} strokeWidth={3} strokeLinecap="round"/>
    </svg>
  );
}

Object.assign(window, {
  PIPI,
  pjit, wobblyPath, wobblyRectPath, wobblyCirclePath, wobblyLinePath, scribblePath,
  ScribbleBox, ScribbleCircle, ScribbleLine, ScribbleFill,
  Pipi, PipiMini, PipiWordmark,
  StoryFairy, StoryMoon, StoryDragon, StorySea, StoryRobot,
  Cloud, Heart, Sparkle, Squiggle,
});
