// V3 — Edward Gorey-inspired character sprites
// Cross-hatched line work, gaunt elongated figures, Victorian mourning
// All sprites: 36x60 viewBox, drawn so feet sit at y=58.

// Shared cross-hatch pattern definitions
const HatchDefs = ({ id }) => (
  <defs>
    <pattern id={`hatch-${id}`} patternUnits="userSpaceOnUse" width="3" height="3" patternTransform="rotate(35)">
      <line x1="0" y1="0" x2="0" y2="3" stroke="#0a0908" strokeWidth="0.4" opacity="0.7"/>
    </pattern>
    <pattern id={`hatch-cross-${id}`} patternUnits="userSpaceOnUse" width="3" height="3" patternTransform="rotate(35)">
      <line x1="0" y1="0" x2="0" y2="3" stroke="#0a0908" strokeWidth="0.5" opacity="0.85"/>
      <line x1="-3" y1="1.5" x2="3" y2="1.5" stroke="#0a0908" strokeWidth="0.3" opacity="0.6"/>
    </pattern>
  </defs>
);

// ======== 1. THE WIDOW ELOISE ========
// Tall woman in mourning — long black dress, veil, pale gaunt face,
// a single jet brooch. Carries a parasol when not blowing.
const WidowEloise = ({ running, jumping, blowing, frame, facing }) => {
  const legSwing = jumping ? 0 : (running ? [0, 1, 0, -1][frame] : 0);
  const armUp = blowing ? -55 : (jumping ? -10 : (running ? [-1, 1, -1, 1][frame] * 5 : 0));
  const skirtSway = running ? [0, 1, 0, -1][frame] : 0;

  return (
    <svg viewBox="0 0 36 60" width="36" height="60" style={{
      overflow: 'visible',
      transform: facing < 0 ? 'scaleX(-1)' : 'none',
    }}>
      <HatchDefs id="we"/>
      <ellipse cx="18" cy="59" rx="11" ry="1.8" fill="#000" opacity="0.5"/>

      {/* legs (mostly hidden under skirt) */}
      <g transform={`translate(${legSwing * 0.3}, 0)`}>
        <rect x="14" y="50" width="3" height="9" fill="#0a0908"/>
        <rect x="19" y="50" width="3" height="9" fill="#0a0908"/>
        <ellipse cx={15.5} cy="58.5" rx="2.5" ry="1.2" fill="#0a0908"/>
        <ellipse cx={20.5} cy="58.5" rx="2.5" ry="1.2" fill="#0a0908"/>
      </g>

      {/* long mourning dress — flared bell shape */}
      <path d={`M 11 30 L ${9 - skirtSway} 52 L ${27 + skirtSway} 52 L 25 30 Z`}
            fill="#0a0908" stroke="#1a1410" strokeWidth="0.5"/>
      {/* dress hatching for texture */}
      <path d={`M 11 30 L ${9 - skirtSway} 52 L ${27 + skirtSway} 52 L 25 30 Z`}
            fill="url(#hatch-we)" opacity="0.6"/>
      {/* skirt hem ruffle */}
      <path d={`M ${9 - skirtSway} 52 Q 13 50 16 52 Q 19 50 22 52 Q 25 50 ${27 + skirtSway} 52`}
            fill="none" stroke="#1a1410" strokeWidth="0.6"/>
      {/* lace at hem */}
      <path d={`M ${9 - skirtSway} 52 L 11 53 L 13 52 L 15 53 L 17 52 L 19 53 L 21 52 L 23 53 L 25 52 L ${27 + skirtSway} 53`}
            fill="none" stroke="#3a342a" strokeWidth="0.4"/>

      {/* high-collared bodice */}
      <path d="M 13 16 L 11 30 L 25 30 L 23 16 Z" fill="#0a0908"/>
      <path d="M 13 16 L 11 30 L 25 30 L 23 16 Z" fill="url(#hatch-cross-we)" opacity="0.4"/>
      {/* jet brooch */}
      <circle cx="18" cy="22" r="1.2" fill="#1a1410" stroke="#3a342a" strokeWidth="0.3"/>
      <circle cx="18" cy="22" r="0.4" fill="#5a4310"/>
      {/* high collar */}
      <path d="M 14 14 L 13 18 L 23 18 L 22 14 Z" fill="#1a1410" stroke="#3a342a" strokeWidth="0.4"/>
      <path d="M 13 17 L 23 17" stroke="#5a4310" strokeWidth="0.3"/>

      {/* arms */}
      <g transform={`rotate(${armUp} 24 19)`}>
        <path d="M 24 17 L 27 32 L 25 33 L 22 19 Z" fill="#0a0908"/>
        {/* gloved hand */}
        <ellipse cx="26" cy="32.5" rx="1.6" ry="2" fill="#0a0908" stroke="#1a1410" strokeWidth="0.3"/>
      </g>
      <g transform={`rotate(${-armUp * 0.3} 12 19)`}>
        <path d="M 12 17 L 9 32 L 11 33 L 14 19 Z" fill="#0a0908"/>
        <ellipse cx="10" cy="32.5" rx="1.6" ry="2" fill="#0a0908" stroke="#1a1410" strokeWidth="0.3"/>
      </g>

      {/* head — gaunt, oval */}
      <ellipse cx="18" cy="10" rx="5.5" ry="7" fill="#e8d8b0"/>
      <ellipse cx="18" cy="10" rx="5.5" ry="7" fill="url(#hatch-we)" opacity="0.15"/>
      {/* hollow eye sockets */}
      <ellipse cx="15.5" cy="10" rx="1" ry="1.3" fill="#0a0908"/>
      <ellipse cx="20.5" cy="10" rx="1" ry="1.3" fill="#0a0908"/>
      <circle cx="15.5" cy="10.2" r="0.3" fill="#fff8e0"/>
      <circle cx="20.5" cy="10.2" r="0.3" fill="#fff8e0"/>
      {/* sharp nose */}
      <path d="M 18 10 L 17.5 13 L 18.5 13 Z" fill="#c8b890"/>
      {/* thin mouth */}
      {blowing
        ? <ellipse cx="18" cy="14" rx="1.2" ry="0.8" fill="#3a1a1a" stroke="#1a0808" strokeWidth="0.2"/>
        : <line x1="16.5" y1="14" x2="19.5" y2="14" stroke="#3a1a1a" strokeWidth="0.6"/>}
      {/* hollow cheeks */}
      <ellipse cx="14" cy="11.5" rx="1" ry="1.5" fill="#c8b890" opacity="0.5"/>
      <ellipse cx="22" cy="11.5" rx="1" ry="1.5" fill="#c8b890" opacity="0.5"/>

      {/* veiled hat — wide brim with veil falling over face */}
      <ellipse cx="18" cy="4" rx="9" ry="2" fill="#0a0908"/>
      <path d="M 13 3 Q 18 -2 23 3 L 23 5 L 13 5 Z" fill="#0a0908"/>
      {/* hat band */}
      <ellipse cx="18" cy="3.5" rx="6" ry="0.8" fill="#3a342a"/>
      {/* veil — translucent net falling over face */}
      <path d="M 9 4 L 11 17 L 25 17 L 27 4 Z" fill="#0a0908" opacity="0.25"/>
      <path d="M 9 4 L 11 17 L 25 17 L 27 4 Z" fill="url(#hatch-we)" opacity="0.3"/>
      {/* veil dots (typical Gorey) */}
      {[5,8,11,14].map((y, i) => [10,14,18,22,26].map((x, j) => (
        <circle key={`${i}-${j}`} cx={x + (i % 2) * 2} cy={y} r="0.4" fill="#0a0908" opacity="0.7"/>
      )))}
    </svg>
  );
};

// ======== 2. THE GENT — MR. AUGUSTUS BRINE ========
// Pencil-thin gentleman in tailcoat, top hat, monocle, walking stick
const MrBrine = ({ running, jumping, blowing, frame, facing }) => {
  const legSwing = jumping ? 0 : (running ? [0, 2, 0, -2][frame] : 0);
  const armUp = blowing ? -55 : (jumping ? -10 : (running ? [-1, 1, -1, 1][frame] * 5 : 0));

  return (
    <svg viewBox="0 0 36 60" width="36" height="60" style={{
      overflow: 'visible',
      transform: facing < 0 ? 'scaleX(-1)' : 'none',
    }}>
      <HatchDefs id="mb"/>
      <ellipse cx="18" cy="59" rx="11" ry="1.8" fill="#000" opacity="0.5"/>

      {/* trousers — pinstripes */}
      <g transform={`translate(${legSwing * 0.3}, 0)`}>
        <path d={`M 14 32 L ${13 - legSwing} 56 L ${15.5 - legSwing} 56 L 16 32 Z`} fill="#1a1410"/>
        <path d={`M 20 32 L ${20.5 + legSwing} 56 L ${23 + legSwing} 56 L 22 32 Z`} fill="#1a1410"/>
        {/* pinstripes */}
        <line x1="14.5" y1="32" x2={13.5 - legSwing} y2="56" stroke="#3a342a" strokeWidth="0.3"/>
        <line x1="20.5" y1="32" x2={21 + legSwing} y2="56" stroke="#3a342a" strokeWidth="0.3"/>
        {/* shiny shoes */}
        <ellipse cx={14 - legSwing} cy="57" rx="3" ry="1.2" fill="#0a0908"/>
        <ellipse cx={22 + legSwing} cy="57" rx="3" ry="1.2" fill="#0a0908"/>
        <ellipse cx={14 - legSwing} cy="56.5" rx="1.5" ry="0.4" fill="#5a4310" opacity="0.8"/>
        <ellipse cx={22 + legSwing} cy="56.5" rx="1.5" ry="0.4" fill="#5a4310" opacity="0.8"/>
      </g>

      {/* tailcoat tails (back) */}
      <path d="M 11 30 L 9 48 L 14 46 L 14 30 Z" fill="#0a0908"/>
      <path d="M 25 30 L 27 48 L 22 46 L 22 30 Z" fill="#0a0908"/>
      <path d="M 11 30 L 9 48 L 14 46 L 14 30 Z" fill="url(#hatch-mb)" opacity="0.4"/>
      <path d="M 25 30 L 27 48 L 22 46 L 22 30 Z" fill="url(#hatch-mb)" opacity="0.4"/>

      {/* tailcoat front + waistcoat */}
      <path d="M 13 18 L 11 32 L 25 32 L 23 18 Z" fill="#0a0908"/>
      <path d="M 13 18 L 11 32 L 25 32 L 23 18 Z" fill="url(#hatch-cross-mb)" opacity="0.35"/>
      {/* white shirt + bow tie */}
      <path d="M 16 18 L 15 30 L 21 30 L 20 18 Z" fill="#e8d8b0"/>
      <path d="M 16 19 L 16 28" stroke="#5a4310" strokeWidth="0.3"/>
      <path d="M 17 22 L 17 28" stroke="#5a4310" strokeWidth="0.2"/>
      <circle cx="18" cy="23" r="0.4" fill="#5a4310"/>
      <circle cx="18" cy="26" r="0.4" fill="#5a4310"/>
      {/* bow tie */}
      <path d="M 15 18 L 18 19 L 21 18 L 20 20 L 18 19.5 L 16 20 Z" fill="#0a0908"/>

      {/* arms */}
      <g transform={`rotate(${armUp} 24 21)`}>
        <path d="M 24 18 L 27 33 L 25 34 L 22 20 Z" fill="#0a0908"/>
        <ellipse cx="26" cy="33.5" rx="1.6" ry="2" fill="#e8d8b0"/>
      </g>
      <g transform={`rotate(${-armUp * 0.3} 12 21)`}>
        <path d="M 12 18 L 9 33 L 11 34 L 14 20 Z" fill="#0a0908"/>
        {/* walking stick (resting) */}
        <line x1="9" y1="33" x2="7" y2="48" stroke="#3a342a" strokeWidth="0.7"/>
        <circle cx="7" cy="48" r="0.8" fill="#d4a84b"/>
      </g>

      {/* head — narrower, longer */}
      <ellipse cx="18" cy="11" rx="5" ry="6.5" fill="#e8d8b0"/>
      <ellipse cx="18" cy="11" rx="5" ry="6.5" fill="url(#hatch-mb)" opacity="0.12"/>
      {/* monocle */}
      <circle cx="20.5" cy="11" r="2" fill="none" stroke="#0a0908" strokeWidth="0.6"/>
      <circle cx="20.5" cy="11" r="2" fill="rgba(155,213,255,0.15)"/>
      <line x1="22.5" y1="11" x2="24" y2="14" stroke="#0a0908" strokeWidth="0.3"/>
      {/* eyes — pinpricks */}
      <circle cx="15.5" cy="11" r="0.5" fill="#0a0908"/>
      <circle cx="20.5" cy="11" r="0.5" fill="#0a0908"/>
      {/* thin mustache */}
      <path d="M 15 14 Q 18 13.5 21 14" stroke="#0a0908" strokeWidth="0.5" fill="none"/>
      {/* mouth */}
      {blowing
        ? <ellipse cx="18" cy="15" rx="1.2" ry="0.8" fill="#3a1a1a"/>
        : <line x1="16.5" y1="15" x2="19.5" y2="15" stroke="#3a1a1a" strokeWidth="0.5"/>}
      {/* sharp chin */}
      <path d="M 17 16 L 18 17.5 L 19 16" fill="#c8b890"/>

      {/* top hat */}
      <ellipse cx="18" cy="4.5" rx="7" ry="1.2" fill="#0a0908"/>
      <rect x="13" y="-3" width="10" height="8" fill="#0a0908"/>
      <rect x="13" y="-3" width="10" height="8" fill="url(#hatch-cross-mb)" opacity="0.3"/>
      {/* hat band */}
      <rect x="13" y="3" width="10" height="1.2" fill="#3a342a"/>
      {/* shine on hat */}
      <line x1="14.5" y1="-2" x2="14.5" y2="3" stroke="#3a342a" strokeWidth="0.3" opacity="0.6"/>
    </svg>
  );
};

// ======== 3. THE WAIF — LITTLE INK ========
// Small child in a sailor outfit, big head, expressionless. Quintessential Gorey.
const LittleInk = ({ running, jumping, blowing, frame, facing }) => {
  const legSwing = jumping ? 0 : (running ? [0, 1, 0, -1][frame] : 0);
  const armUp = blowing ? -55 : (jumping ? -10 : (running ? [-1, 1, -1, 1][frame] * 4 : 0));

  return (
    <svg viewBox="0 0 36 60" width="36" height="60" style={{
      overflow: 'visible',
      transform: facing < 0 ? 'scaleX(-1)' : 'none',
    }}>
      <HatchDefs id="li"/>
      <ellipse cx="18" cy="59" rx="9" ry="1.6" fill="#000" opacity="0.5"/>

      {/* socks + buckled shoes */}
      <g transform={`translate(${legSwing * 0.3}, 0)`}>
        <rect x={14} y="44" width="3" height="13" fill="#e8d8b0"/>
        <rect x={19} y="44" width="3" height="13" fill="#e8d8b0"/>
        {/* sock stripe */}
        <line x1={14} y1="48" x2={17} y2="48" stroke="#0a0908" strokeWidth="0.5"/>
        <line x1={19} y1="48" x2={22} y2="48" stroke="#0a0908" strokeWidth="0.5"/>
        {/* buckled mary janes */}
        <ellipse cx={15.5} cy="58" rx="2.8" ry="1.2" fill="#0a0908"/>
        <ellipse cx={20.5} cy="58" rx="2.8" ry="1.2" fill="#0a0908"/>
        <rect x={14.7} y="56.5" width="1.6" height="0.6" fill="#d4a84b"/>
        <rect x={19.7} y="56.5" width="1.6" height="0.6" fill="#d4a84b"/>
      </g>

      {/* shorts/skirt — sailor */}
      <path d="M 12 36 L 11 46 L 25 46 L 24 36 Z" fill="#0a0908"/>
      <path d="M 12 36 L 11 46 L 25 46 L 24 36 Z" fill="url(#hatch-li)" opacity="0.35"/>

      {/* sailor blouse — white with deep blue collar */}
      <path d="M 13 23 L 12 38 L 24 38 L 23 23 Z" fill="#e8d8b0"/>
      <path d="M 13 23 L 12 38 L 24 38 L 23 23 Z" fill="url(#hatch-li)" opacity="0.18"/>
      {/* sailor collar — wide V */}
      <path d="M 13 23 L 16 23 L 18 30 L 20 23 L 23 23 L 24 27 L 18 32 L 12 27 Z" fill="#1a1410"/>
      <line x1="13" y1="25" x2="22" y2="25" stroke="#5a4310" strokeWidth="0.3"/>
      <line x1="14" y1="26.5" x2="21" y2="26.5" stroke="#5a4310" strokeWidth="0.2"/>
      {/* tie */}
      <path d="M 17 30 L 18 38 L 19 30 Z" fill="#3a1a1a"/>
      <ellipse cx="18" cy="30" rx="1.5" ry="0.6" fill="#1a1410"/>

      {/* arms */}
      <g transform={`rotate(${armUp} 24 25)`}>
        <path d="M 24 23 L 26 33 L 24 34 L 22 24 Z" fill="#e8d8b0"/>
        <ellipse cx="25" cy="33.5" rx="1.4" ry="1.6" fill="#e8d8b0"/>
      </g>
      <g transform={`rotate(${-armUp * 0.3} 12 25)`}>
        <path d="M 12 23 L 10 33 L 12 34 L 14 24 Z" fill="#e8d8b0"/>
        <ellipse cx="11" cy="33.5" rx="1.4" ry="1.6" fill="#e8d8b0"/>
      </g>

      {/* big round head — proportionally oversized (Gorey waif) */}
      <ellipse cx="18" cy="14" rx="7.5" ry="8" fill="#e8d8b0"/>
      <ellipse cx="18" cy="14" rx="7.5" ry="8" fill="url(#hatch-li)" opacity="0.12"/>
      {/* pageboy bowl-cut hair */}
      <path d="M 10.5 11 Q 10 4 18 4 Q 26 4 25.5 11 L 24 11 Q 23 9 18 9 Q 13 9 12 11 Z" fill="#0a0908"/>
      <path d="M 10.5 11 Q 10 4 18 4 Q 26 4 25.5 11 L 24 11 Q 23 9 18 9 Q 13 9 12 11 Z" fill="url(#hatch-cross-li)" opacity="0.4"/>
      {/* fringe */}
      <path d="M 11 11 Q 13 8 14 11" stroke="#0a0908" strokeWidth="0.4" fill="none"/>
      <path d="M 22 11 Q 24 8 25 11" stroke="#0a0908" strokeWidth="0.4" fill="none"/>

      {/* huge dot eyes (signature Gorey waif) */}
      <circle cx="14.5" cy="15" r="1.4" fill="#0a0908"/>
      <circle cx="21.5" cy="15" r="1.4" fill="#0a0908"/>
      <circle cx="14.8" cy="14.7" r="0.4" fill="#fff8e0"/>
      <circle cx="21.8" cy="14.7" r="0.4" fill="#fff8e0"/>
      {/* nose dot */}
      <circle cx="18" cy="17.5" r="0.3" fill="#3a342a"/>
      {/* tiny mouth */}
      {blowing
        ? <circle cx="18" cy="19.5" r="0.9" fill="#3a1a1a"/>
        : <line x1="17" y1="19.5" x2="19" y2="19.5" stroke="#3a1a1a" strokeWidth="0.5"/>}

      {/* sailor hat */}
      <ellipse cx="18" cy="5" rx="6" ry="1.4" fill="#e8d8b0"/>
      <path d="M 13 2 Q 18 -1 23 2 L 23 5 L 13 5 Z" fill="#e8d8b0"/>
      <path d="M 13 2 Q 18 -1 23 2 L 23 5 L 13 5 Z" fill="url(#hatch-li)" opacity="0.15"/>
      <path d="M 13 4 L 23 4" stroke="#1a1410" strokeWidth="0.4"/>
    </svg>
  );
};

// ======== Character roster ========
const CHARACTERS = [
  {
    id: 'eloise',
    name: 'Widow Eloise',
    title: 'in mourning, on the prowl',
    Component: WidowEloise,
    blurb: 'Bereaved seven times. Still hungry.',
    stats: { speed: 2, jump: 3, range: 3 },
  },
  {
    id: 'brine',
    name: 'Mr. Brine',
    title: 'gentleman of leisure',
    Component: MrBrine,
    blurb: 'A monocle. A grievance. A talent for bubbles.',
    stats: { speed: 3, jump: 2, range: 3 },
  },
  {
    id: 'ink',
    name: 'Little Ink',
    title: 'orphan, indeterminate',
    Component: LittleInk,
    blurb: 'No one quite remembers where the child came from.',
    stats: { speed: 4, jump: 4, range: 1 },
  },
];

// Expose for other scripts
Object.assign(window, {
  WidowEloise, MrBrine, LittleInk, CHARACTERS,
});
