/* ============================================================================
   MOWDEW LIVE DEMO — shared widgets
   Detailed papercraft personas (+ circular face avatars), persona headers,
   flow trackers, record-mark statuses, sync ticker, demo notification bell.
   The three phones live in mowdew-demo-phones.jsx + mowdew-demo-tabs.jsx;
   the world state machine lives in Mowdew Live Demo.html.
   ========================================================================= */

function dmClock(sec) {
  const m = Math.floor(sec / 60), s = sec % 60;
  return `${m}:${String(s).padStart(2, '0')}`;
}

/* ─── Papercraft personas v3 — detailed cut-paper busts, calm poses.
   Every garment is layered like real paper: occlusion slivers under each
   overlapping piece, a catch-light on the left paper edge, darker right
   facets (left-lit). Persona-defining details: Diego wears glasses, a
   lanyard ID and a watch, tablet under his arm; Marco has his cap with
   stitching, a shoulder towel, name badge and gripped pool pole; Emma a
   knit cardigan, scrunchie bun, freckles and a leaf-print mug.
   Face box unchanged (x57-113 / y22-78) so PaperAvatar crops stay valid.  */

function PaperOwner({ size = 118 }) {
  return (
    <svg width={size} height={size * 1.06} viewBox="0 0 170 180" style={{ filter: 'drop-shadow(0 7px 9px rgba(27,26,23,.20))' }} aria-label="Diego — business owner">
      <ellipse cx="85" cy="171" rx="49" ry="7" fill="#1B1A17" opacity=".1" />
      {/* neck + chin shadow */}
      <path d="M77 74 h16 v22 a8 8 0 0 1 -16 0 Z" fill="#B3784E" />
      <path d="M77 74 h16 v9 q-8 5.5 -16 0 Z" fill="#96623B" />
      {/* torso — leaf polo, broad shoulders */}
      <path d="M44 170 L45 133 Q47 114 62 106 Q74 100 85 99 Q96 100 108 106 Q123 114 125 133 L126 170 Z" fill="#21A84F" />
      <path d="M85 99 Q96 100 108 106 Q123 114 125 133 L126 170 L85 170 Z" fill="#157A39" opacity=".42" />
      <path d="M44 170 L45 133 Q47 114 62 106 L64 109 Q50 117 48 134 L47 170 Z" fill="#fff" opacity=".14" />
      <path d="M58 110 Q68 104 76 102 M112 110 Q102 104 94 102" stroke="#157A39" strokeWidth="1.4" fill="none" opacity=".5" />
      {/* collar */}
      <path d="M70 104 L85 99 L83 114 L71 110 Z" fill="#FBFAF6" />
      <path d="M100 104 L85 99 L87 114 L99 110 Z" fill="#E4E0D2" />
      <path d="M83 114 L85 99 L87 114 L85 117 Z" fill="#15803C" />
      {/* lanyard + ID card */}
      <path d="M75 106 Q83 119 84 127 M95 106 Q87 119 86 127" stroke="#15803C" strokeWidth="2.6" fill="none" />
      <rect x="79" y="126" width="12" height="15" rx="2" fill="#FBFAF6" />
      <rect x="79" y="126" width="12" height="3.4" rx="1.6" fill="#21A84F" />
      <rect x="81.5" y="131.5" width="4" height="4.5" rx="1" fill="#46B6F0" />
      <rect x="87" y="131.5" width="2.4" height="1.6" rx=".8" fill="#C9C4B6" />
      <rect x="87" y="134.5" width="2.4" height="1.6" rx=".8" fill="#C9C4B6" />
      {/* chest pocket + pen */}
      <rect x="100" y="122" width="14" height="14" rx="2.5" fill="#1B9647" />
      <path d="M100 124.5 h14" stroke="#157A39" strokeWidth="1.3" />
      <rect x="103.5" y="117" width="3" height="9" rx="1.5" fill="#FFCB3D" />
      {/* right arm — cuff, watch, hand with thumb */}
      <path d="M114 110 Q124 117 125 131 L125 146 Q125 152 119 152 L113 149 Q116 132 112 114 Z" fill="#127A38" />
      <path d="M113 148 L119 151 L119 155 L113 152 Z" fill="#0F6630" />
      <rect x="112" y="152.5" width="10" height="4" rx="2" fill="#6E6B60" />
      <circle cx="117" cy="154.5" r="3" fill="#ECE9E1" stroke="#1B1A17" strokeWidth="1.2" />
      <circle cx="117" cy="162" r="6.5" fill="#B3784E" />
      <circle cx="113.5" cy="159.5" r="2.6" fill="#A86F47" />
      {/* left arm + tablet under it */}
      <path d="M56 110 Q46 117 45 131 L45 146 Q45 152 51 152 L57 149 Q54 132 58 114 Z" fill="#1B9647" />
      <path d="M51 149 L57 146 L57 150 L51 153 Z" fill="#157A39" />
      <g transform="rotate(-7 47 142)">
        <rect x="33" y="124" width="27" height="36" rx="4" fill="#1B1A17" />
        <rect x="36" y="127" width="21" height="30" rx="2.5" fill="#FBFAF6" />
        <rect x="36" y="127" width="21" height="6" rx="2.5" fill="#E9F8EE" />
        <rect x="39" y="136" width="15" height="2.4" rx="1.2" fill="#ECE9E1" />
        <rect x="39" y="141" width="11" height="2.4" rx="1.2" fill="#ECE9E1" />
        <rect x="39" y="146" width="13" height="2.4" rx="1.2" fill="#ECE9E1" />
        <circle cx="52" cy="152.5" r="2.6" fill="#21A84F" />
      </g>
      <circle cx="53" cy="158" r="6.5" fill="#C98E63" />
      <circle cx="57" cy="155" r="2.6" fill="#B3784E" />
      {/* ears */}
      <circle cx="63" cy="56" r="5.2" fill="#B3784E" /><circle cx="63.5" cy="56" r="2" fill="#96623B" />
      <circle cx="107" cy="56" r="5.2" fill="#A86F47" /><circle cx="106.5" cy="56" r="2" fill="#8E5A33" />
      {/* head + shade + under-fringe occlusion */}
      <path d="M85 24 Q104 24 106 44 Q107 56 104 65 Q100 78 91 83 Q88 85 85 85 Q82 85 79 83 Q70 78 66 65 Q63 56 64 44 Q66 24 85 24 Z" fill="#C98E63" />
      <path d="M85 24 Q104 24 106 44 Q107 56 104 65 Q100 78 91 83 Q88 85 85 85 L85 24 Z" fill="#B3784E" opacity=".32" />
      <path d="M65 46 Q70 36 80 33 Q85 32 90 33 Q100 36 105 46 Q98 39 85 38 Q72 39 65 46 Z" fill="#96623B" opacity=".28" />
      {/* hair — two-tone crop, faded sides */}
      <path d="M63 50 Q62 27 76 21 Q85 18 94 21 Q108 27 107 50 Q104 36 95 32 Q90 30 85 30 Q80 30 75 32 Q66 36 63 50 Z" fill="#2A2118" />
      <path d="M94 21 Q108 27 107 50 Q104 36 95 32 Z" fill="#16100B" />
      <path d="M63 52 Q63 42 67 37 L67 56 Q64 55 63 52 Z" fill="#231B12" />
      <path d="M107 52 Q107 42 103 37 L103 56 Q106 55 107 52 Z" fill="#16100B" />
      {/* brows */}
      <path d="M71 50.5 Q76 48.5 80 50.5" stroke="#2A2118" strokeWidth="2.8" strokeLinecap="round" fill="none" />
      <path d="M90 50.5 Q94 48.5 99 50.5" stroke="#1A140E" strokeWidth="2.8" strokeLinecap="round" fill="none" />
      {/* glasses + eyes */}
      <rect x="68.5" y="53.5" width="15" height="11.5" rx="4.5" fill="rgba(255,255,255,.16)" stroke="#1B1A17" strokeWidth="2" />
      <rect x="86.5" y="53.5" width="15" height="11.5" rx="4.5" fill="rgba(255,255,255,.16)" stroke="#1B1A17" strokeWidth="2" />
      <path d="M83.5 58 L86.5 58" stroke="#1B1A17" strokeWidth="2" />
      <path d="M68.5 57.5 L64 55.5 M101.5 57.5 L106 55.5" stroke="#1B1A17" strokeWidth="1.8" strokeLinecap="round" />
      <circle cx="76" cy="59.5" r="2.6" fill="#1B1A17" /><circle cx="77" cy="58.7" r=".9" fill="#fff" />
      <circle cx="94" cy="59.5" r="2.6" fill="#1B1A17" /><circle cx="95" cy="58.7" r=".9" fill="#fff" />
      {/* nose + smile + blush */}
      <path d="M85 62 Q87 66 85.5 69" stroke="#A86F47" strokeWidth="2.2" strokeLinecap="round" fill="none" />
      <path d="M78 73.5 Q85 79 92 73.5" stroke="#1B1A17" strokeWidth="2.4" strokeLinecap="round" fill="none" />
      <path d="M81 77.8 Q85 79.6 89 77.8" stroke="#A86F47" strokeWidth="1.4" strokeLinecap="round" fill="none" opacity=".6" />
      <ellipse cx="70.5" cy="67" rx="3.2" ry="1.9" fill="#F2683C" opacity=".15" />
      <ellipse cx="99.5" cy="67" rx="3.2" ry="1.9" fill="#F2683C" opacity=".13" />
    </svg>
  );
}

function PaperPro({ size = 118 }) {
  return (
    <svg width={size} height={size * 1.06} viewBox="0 0 170 180" style={{ filter: 'drop-shadow(0 7px 9px rgba(27,26,23,.20))' }} aria-label="Marco — pro">
      <ellipse cx="85" cy="171" rx="49" ry="7" fill="#1B1A17" opacity=".1" />
      {/* pool pole — standing in his grip, taped */}
      <ellipse cx="139" cy="29" rx="13" ry="9" fill="none" stroke="#0A767F" strokeWidth="4" transform="rotate(-16 139 29)" />
      <path d="M130 25 l17 8 M129 31 l19 3 M134 21 l9 14" stroke="#0A767F" strokeWidth="1" opacity=".5" />
      <rect x="132" y="37" width="5" height="127" rx="2.5" fill="#A8A498" />
      <rect x="135" y="37" width="2" height="127" fill="#8C8676" />
      <rect x="131" y="137" width="7" height="3" fill="#6E6B60" />
      <rect x="131" y="156" width="7" height="3" fill="#6E6B60" />
      {/* neck */}
      <path d="M77 74 h16 v22 a8 8 0 0 1 -16 0 Z" fill="#CE9565" />
      <path d="M77 74 h16 v9 q-8 5.5 -16 0 Z" fill="#B17A4B" />
      {/* torso — aqua work shirt */}
      <path d="M46 170 L47 134 Q49 115 63 107 Q74 101 85 100 Q96 101 107 107 Q121 115 123 134 L124 170 Z" fill="#12BCC9" />
      <path d="M85 100 Q96 101 107 107 Q121 115 123 134 L124 170 L85 170 Z" fill="#0B838D" opacity=".4" />
      <path d="M46 170 L47 134 Q49 115 63 107 L65 110 Q52 118 50 135 L49 170 Z" fill="#fff" opacity=".14" />
      <path d="M60 112 Q72 105 85 104 Q98 105 110 112" stroke="#0B838D" strokeWidth="1.4" fill="none" opacity=".55" />
      {/* collar + zip + pull */}
      <path d="M71 105 L85 100 L83 114 L72 110 Z" fill="#10A9B5" />
      <path d="M99 105 L85 100 L87 114 L98 110 Z" fill="#0A767F" />
      <rect x="82.5" y="112" width="5" height="23" rx="2" fill="#0A767F" />
      <rect x="83.6" y="113" width="2.8" height="20" rx="1.4" fill="#0E98A3" />
      <rect x="83" y="134" width="4" height="6" rx="1.6" fill="#FFCB3D" />
      {/* towel over the left shoulder */}
      <path d="M64 103 L78 99 L82 130 L70 133 Z" fill="#ECE9E1" />
      <path d="M64 103 L78 99 L79 106 L65 110 Z" fill="#FBFAF6" />
      <path d="M70 129 L82 126 L82 130 L70 133 Z" fill="#12BCC9" opacity=".55" />
      <path d="M69 112 L80 109 M70 119 L81 116" stroke="#C9C4B6" strokeWidth="1.2" opacity=".7" />
      {/* name badge */}
      <rect x="96" y="121" width="18" height="13" rx="2.5" fill="#FBFAF6" />
      <rect x="98.5" y="124" width="6" height="7" rx="1.5" fill="#46B6F0" />
      <rect x="106.5" y="124.5" width="5" height="2" rx="1" fill="#C9C4B6" />
      <rect x="106.5" y="128" width="5" height="2" rx="1" fill="#C9C4B6" />
      {/* left arm + cuff + hand */}
      <path d="M58 111 Q48 118 47 132 L47 147 Q47 153 53 153 L59 150 Q56 133 60 115 Z" fill="#10A9B5" />
      <path d="M47 144 L59 147 L59 151 L47 148 Z" fill="#0A767F" opacity=".7" />
      <circle cx="53" cy="159" r="6.5" fill="#E0A878" />
      <circle cx="57" cy="156" r="2.6" fill="#CE9565" />
      {/* right arm gripping the pole */}
      <path d="M110 111 Q124 118 129 133 L133 142 L124 147 L114 129 Z" fill="#0A767F" />
      <path d="M124 143 L133 138 L134 142 L125 147 Z" fill="#08616A" opacity=".8" />
      <circle cx="131" cy="147" r="7" fill="#CE9565" />
      <circle cx="127" cy="143.5" r="2.6" fill="#B17A4B" />
      {/* ears */}
      <circle cx="63" cy="56" r="5.2" fill="#CE9565" /><circle cx="63.5" cy="56" r="2" fill="#B17A4B" />
      <circle cx="107" cy="56" r="5.2" fill="#BC8254" /><circle cx="106.5" cy="56" r="2" fill="#A06A3D" />
      {/* head + shade */}
      <path d="M85 24 Q104 24 106 44 Q107 56 104 65 Q100 78 91 83 Q88 85 85 85 Q82 85 79 83 Q70 78 66 65 Q63 56 64 44 Q66 24 85 24 Z" fill="#E0A878" />
      <path d="M85 24 Q104 24 106 44 Q107 56 104 65 Q100 78 91 83 Q88 85 85 85 L85 24 Z" fill="#CE9565" opacity=".32" />
      {/* brim shadow */}
      <path d="M62 52 Q85 44 108 52 Q85 48.5 62 52 Z" fill="#B17A4B" opacity=".3" />
      {/* cap — dome, seams, button, droplet patch, brim */}
      <path d="M62 46 Q62 23 78 18 Q85 16 92 18 Q108 23 108 46 L106 48 Q102 33 90 30 Q85 29 80 30 Q68 33 64 48 Z" fill="#46B6F0" />
      <path d="M92 18 Q108 23 108 46 L106 48 Q102 33 90 30 Z" fill="#2E9FDC" />
      <path d="M85 16.5 L85 29.5" stroke="#2E9FDC" strokeWidth="1.6" />
      <path d="M74 19.5 Q70 26 67 36 M96 19.5 Q100 26 103 36" stroke="#2E9FDC" strokeWidth="1.2" opacity=".7" fill="none" />
      <circle cx="85" cy="17" r="2" fill="#1F86C2" />
      <circle cx="85" cy="25.5" r="4.6" fill="#FBFAF6" />
      <path d="M85 22.2 c1.9 2.2 2.9 3.4 2.9 4.7 a2.9 2.9 0 1 1 -5.8 0 c0-1.3 1-2.5 2.9-4.7 Z" fill="#12BCC9" />
      <path d="M56 47 Q85 38 114 47 L112 53 Q85 45 58 53 Z" fill="#1F86C2" />
      <path d="M57 49.5 Q85 41.5 113 49.5" stroke="#16699C" strokeWidth="1" opacity=".6" fill="none" />
      {/* face */}
      <path d="M71 51 Q76 49 80 51" stroke="#7A4F2B" strokeWidth="2.8" strokeLinecap="round" fill="none" />
      <path d="M90 51 Q94 49 99 51" stroke="#6B431F" strokeWidth="2.8" strokeLinecap="round" fill="none" />
      <circle cx="76" cy="59" r="2.7" fill="#1B1A17" /><circle cx="77" cy="58.2" r=".9" fill="#fff" />
      <circle cx="94" cy="59" r="2.7" fill="#1B1A17" /><circle cx="95" cy="58.2" r=".9" fill="#fff" />
      <path d="M85 61.5 Q87 65.5 85.5 68.5" stroke="#B17A4B" strokeWidth="2.2" strokeLinecap="round" fill="none" />
      <path d="M78 73 Q85 78.5 92 73" stroke="#1B1A17" strokeWidth="2.4" strokeLinecap="round" fill="none" />
      <path d="M81 77.4 Q85 79.2 89 77.4" stroke="#B17A4B" strokeWidth="1.4" strokeLinecap="round" fill="none" opacity=".6" />
      <ellipse cx="70.5" cy="66.5" rx="3.2" ry="1.9" fill="#F2683C" opacity=".18" />
      <ellipse cx="99.5" cy="66.5" rx="3.2" ry="1.9" fill="#F2683C" opacity=".15" />
    </svg>
  );
}

function PaperHome({ size = 118 }) {
  return (
    <svg width={size} height={size * 1.06} viewBox="0 0 170 180" style={{ filter: 'drop-shadow(0 7px 9px rgba(27,26,23,.20))' }} aria-label="Emma — homeowner">
      <ellipse cx="85" cy="171" rx="49" ry="7" fill="#1B1A17" opacity=".1" />
      {/* neck */}
      <path d="M77 74 h16 v22 a8 8 0 0 1 -16 0 Z" fill="#DCA87B" />
      <path d="M77 74 h16 v9 q-8 5.5 -16 0 Z" fill="#C18C5B" />
      {/* tee */}
      <path d="M50 170 L51 134 Q53 116 66 108 Q76 102 85 101 Q94 102 104 108 Q117 116 119 134 L120 170 Z" fill="#FBFAF6" />
      <path d="M85 101 Q94 102 104 108 Q117 116 119 134 L120 170 L85 170 Z" fill="#E4E0D2" opacity=".5" />
      {/* necklace */}
      <path d="M78 107 Q85 115 92 107" stroke="#E5B22E" strokeWidth="1.6" fill="none" />
      <circle cx="85" cy="114" r="1.8" fill="#FFCB3D" />
      {/* cardigan — shawl collar, knit marks, buttons */}
      <path d="M50 170 L51 134 Q53 116 66 108 L74 104 L72 170 Z" fill="#FFCB3D" />
      <path d="M120 170 L119 134 Q117 116 104 108 L96 104 L98 170 Z" fill="#E5B22E" />
      <path d="M66 108 L74 104 L75 109 L68 112 Z" fill="#D9A724" opacity=".55" />
      <path d="M104 108 L96 104 L95 109 L102 112 Z" fill="#C79A1F" opacity=".55" />
      <path d="M50 170 L51 134 Q53 116 66 108 L67.5 110.5 Q55 118 53 135 L52 170 Z" fill="#fff" opacity=".18" />
      <path d="M59 124 l3.5 3.5 m-3.5 4.5 l3.5 3.5 m-3.5 4.5 l3.5 3.5 m-3.5 4.5 l3.5 3.5" stroke="#D9A724" strokeWidth="1.1" opacity=".65" fill="none" />
      <path d="M111 124 l-3.5 3.5 m3.5 4.5 l-3.5 3.5 m3.5 4.5 l-3.5 3.5 m3.5 4.5 l-3.5 3.5" stroke="#C79A1F" strokeWidth="1.1" opacity=".65" fill="none" />
      <circle cx="69" cy="130" r="1.4" fill="#D9A724" /><circle cx="69" cy="140" r="1.4" fill="#D9A724" />
      {/* arms curve in to the mug + cuffs */}
      <path d="M60 112 Q49 120 51 134 Q53 145 64 149 L69 142 Q61 138 61 128 Q61 118 66 112 Z" fill="#F4C238" />
      <path d="M64 149 L69 142 L66 140 L61 146 Z" fill="#D9A724" opacity=".7" />
      <path d="M110 112 Q121 120 119 134 Q117 145 106 149 L101 142 Q109 138 109 128 Q109 118 104 112 Z" fill="#D9A724" />
      <path d="M106 149 L101 142 L104 140 L109 146 Z" fill="#C79A1F" opacity=".7" />
      {/* steam + mug with leaf print, both hands w/ thumbs */}
      <path d="M80 121 q2 -4 0 -7 M90 121 q-2 -4 0 -7" stroke="#C9C4B6" strokeWidth="1.6" fill="none" strokeLinecap="round" />
      <rect x="72" y="128" width="26" height="21" rx="4" fill="#12BCC9" />
      <path d="M85 128 h9 a4 4 0 0 1 4 4 v13 a4 4 0 0 1 -4 4 h-9 Z" fill="#0E98A3" opacity=".5" />
      <path d="M78 138 c2.5 -4.5 7 -4.5 8 -1 c-3.5 3.5 -7 3 -8 1 Z" fill="#E9F8EE" />
      <path d="M78.5 138.5 c3 -1.5 5.5 -2 7 -1.5" stroke="#21A84F" strokeWidth=".9" fill="none" opacity=".7" />
      <rect x="71" y="126" width="28" height="4.5" rx="2.2" fill="#FBFAF6" />
      <path d="M99 133 q7 3.5 0 10" stroke="#0E98A3" strokeWidth="3.2" fill="none" />
      <circle cx="70" cy="144" r="6.5" fill="#EBBE93" />
      <circle cx="74" cy="140.5" r="2.6" fill="#DCA87B" />
      <circle cx="100" cy="144" r="6.5" fill="#DCA87B" />
      <circle cx="96" cy="140.5" r="2.6" fill="#C18C5B" />
      {/* ears + hoops */}
      <circle cx="63" cy="56" r="5.2" fill="#DCA87B" /><circle cx="63.5" cy="56" r="2" fill="#C18C5B" />
      <circle cx="107" cy="56" r="5.2" fill="#C99465" /><circle cx="106.5" cy="56" r="2" fill="#AD7B4C" />
      <circle cx="64" cy="65.5" r="2.4" fill="none" stroke="#E5B22E" strokeWidth="1.6" />
      <circle cx="106" cy="65.5" r="2.4" fill="none" stroke="#D9A724" strokeWidth="1.6" />
      {/* head + shade + under-fringe occlusion */}
      <path d="M85 24 Q104 24 106 44 Q107 56 104 65 Q100 78 91 83 Q88 85 85 85 Q82 85 79 83 Q70 78 66 65 Q63 56 64 44 Q66 24 85 24 Z" fill="#EBBE93" />
      <path d="M85 24 Q104 24 106 44 Q107 56 104 65 Q100 78 91 83 Q88 85 85 85 L85 24 Z" fill="#DCA87B" opacity=".32" />
      <path d="M64 48 Q70 37 80 34 Q85 33 90 34 Q100 37 106 46 Q97 40 85 39 Q72 40 64 48 Z" fill="#C18C5B" opacity=".25" />
      {/* hair — sweep, side piece, bun + coral scrunchie, strand, flyaways */}
      <circle cx="112" cy="28" r="10" fill="#5A3E2B" />
      <path d="M106 24 Q112 20 118 24 Q116 30 110 31 Z" fill="#6B4A33" />
      <ellipse cx="106.5" cy="33" rx="4.6" ry="3" fill="#F2683C" transform="rotate(-32 106.5 33)" />
      <path d="M62 52 Q60 26 78 20 Q85 18 93 20 Q108 25 108 46 Q102 34 90 31 Q85 30 79 32 Q67 36 64 54 Z" fill="#5A3E2B" />
      <path d="M93 20 Q108 25 108 46 Q102 34 90 31 Z" fill="#43301F" />
      <path d="M62 52 Q61 42 65 35 Q63 46 66 56 Q63 55 62 52 Z" fill="#43301F" />
      <path d="M105 42 q4 9 1 17" stroke="#43301F" strokeWidth="2.4" fill="none" strokeLinecap="round" />
      <path d="M66 50 q-2 4 -1 8 M69 46 q-1.5 3 -1 6" stroke="#43301F" strokeWidth="1.1" fill="none" strokeLinecap="round" opacity=".7" />
      {/* face — brows, lashes, eyes, freckles, nose, smile, blush */}
      <path d="M72 51 Q76 49.5 80 51" stroke="#43301F" strokeWidth="2.5" strokeLinecap="round" fill="none" />
      <path d="M90 51 Q94 49.5 98 51" stroke="#43301F" strokeWidth="2.5" strokeLinecap="round" fill="none" />
      <circle cx="76" cy="59" r="2.7" fill="#1B1A17" /><circle cx="77" cy="58.2" r=".9" fill="#fff" />
      <circle cx="94" cy="59" r="2.7" fill="#1B1A17" /><circle cx="95" cy="58.2" r=".9" fill="#fff" />
      <path d="M72.5 56.5 l-2 -1.3 M97.5 56.5 l2 -1.3" stroke="#1B1A17" strokeWidth="1.2" strokeLinecap="round" />
      <circle cx="71" cy="64" r=".75" fill="#C18C5B" opacity=".6" /><circle cx="74" cy="65.5" r=".75" fill="#C18C5B" opacity=".6" />
      <circle cx="96" cy="65.5" r=".75" fill="#C18C5B" opacity=".6" /><circle cx="99" cy="64" r=".75" fill="#C18C5B" opacity=".6" />
      <path d="M85 61.5 Q87 65.5 85.5 68.5" stroke="#C18C5B" strokeWidth="2.2" strokeLinecap="round" fill="none" />
      <path d="M78 72.5 Q85 78 92 72.5" stroke="#1B1A17" strokeWidth="2.4" strokeLinecap="round" fill="none" />
      <path d="M81 77 Q85 78.8 89 77" stroke="#C18C5B" strokeWidth="1.4" strokeLinecap="round" fill="none" opacity=".6" />
      <ellipse cx="70.5" cy="67" rx="3.4" ry="2" fill="#F2683C" opacity=".2" />
      <ellipse cx="99.5" cy="67" rx="3.4" ry="2" fill="#F2683C" opacity=".17" />
    </svg>
  );
}

/* ─── PaperAvatar — circular face crop of the same papercraft figures ── */
function PaperAvatar({ who, size = 40, ring = false }) {
  const P = who === 'owner' ? PaperOwner : who === 'pro' ? PaperPro : PaperHome;
  const k = size / 56;
  return (
    <span style={{ width: size, height: size, borderRadius: '50%', overflow: 'hidden', position: 'relative', flexShrink: 0, background: '#FDF6E3', border: ring ? '2px solid var(--green-500)' : '1px solid var(--ink-100)', boxSizing: 'border-box', display: 'inline-block' }}>
      <span style={{ position: 'absolute', left: -57 * k, top: -22 * k, pointerEvents: 'none', display: 'block' }}>
        <P size={170 * k} />
      </span>
    </span>
  );
}

/* ─── Papercraft scene props — one per persona, same cut-paper language:
   left-lit, darker right facets, soft ground shadow. Sit at the right end
   of each persona header.                                                ─ */
function PaperOffice({ size = 100 }) {
  const h = size * 150 / 240;
  return (
    <svg width={size} height={h} viewBox="0 0 240 150" style={{ filter: 'drop-shadow(0 6px 8px rgba(27,26,23,.18))' }} aria-label="Diego's office with the crew trucks parked out front">
      <ellipse cx="118" cy="142" rx="106" ry="6.5" fill="#1B1A17" opacity=".1" />
      {/* rooftop AC */}
      <polygon points="66,19 84,19 84,29 66,29" fill="#A8A498" />
      <polygon points="84,19 92,22 92,32 84,29" fill="#8C8676" />
      <path d="M70 23 h10 M70 26 h10" stroke="#6E6B60" strokeWidth="1.4" />
      {/* parapet */}
      <polygon points="24,28 100,28 100,37 24,37" fill="#21A84F" />
      <polygon points="100,28 134,40 134,49 100,37" fill="#178A40" />
      {/* walls */}
      <polygon points="98,37 132,49 132,136 98,136" fill="#E8E4D8" />
      <polygon points="26,37 98,37 98,136 26,136" fill="#FBFAF6" />
      {/* front windows — 2 × 3 */}
      {[48, 72, 96].map(y => (
        <g key={y}>
          <rect x="36" y={y} width="18" height="13" fill="#BFE9FA" stroke="#fff" strokeWidth="2.4" />
          <rect x="68" y={y} width="18" height="13" fill="#BFE9FA" stroke="#fff" strokeWidth="2.4" />
        </g>
      ))}
      {/* side windows */}
      <polygon points="106,58 126,65 126,77 106,70" fill="#9FD0DD" />
      <polygon points="106,84 126,91 126,103 106,96" fill="#9FD0DD" />
      {/* awning + glass door + logo plate */}
      <polygon points="46,110 80,110 84,118 42,118" fill="#21A84F" />
      <polygon points="46,110 80,110 80,113 46,113" fill="#1B9647" />
      <rect x="56" y="118" width="16" height="18" fill="#9FD0DD" stroke="#6E6B60" strokeWidth="2" />
      <line x1="64" y1="118" x2="64" y2="136" stroke="#6E6B60" strokeWidth="1.6" />
      <rect x="32" y="120" width="13" height="13" rx="3.5" fill="#21A84F" />
      <path d="M38.5 123 c1.7 2 2.6 3.1 2.6 4.3 a2.6 2.6 0 1 1 -5.2 0 c0-1.2 .9-2.3 2.6-4.3 Z" fill="#FBFAF6" />
      {/* the crew fleet — same aqua trucks, parked out front */}
      {[[108, 107, 0.58], [172, 107, 0.58]].map(([tx, ty, s], i) => (
        <g key={i} transform={'translate(' + tx + ' ' + ty + ') scale(' + s + ')'}>
          <ellipse cx="50" cy="56" rx="48" ry="4.5" fill="#1B1A17" opacity=".08" />
          <rect x="4" y="28" width="92" height="18" fill="#12BCC9" />
          <rect x="48" y="28" width="48" height="18" fill="#0E98A3" opacity=".5" />
          <rect x="4" y="42" width="92" height="4" fill="#0E98A3" />
          <rect x="46" y="25" width="50" height="4" fill="#0A767F" />
          <polygon points="12,12 36,12 44,28 6,28" fill="#12BCC9" />
          <polygon points="16,16 33,16 38,26 12,26" fill="#BFE9FA" />
          <circle cx="26" cy="36" r="5" fill="#FBFAF6" />
          <path d="M26 33 c1.2 1.4 1.9 2.2 1.9 3 a1.9 1.9 0 1 1 -3.8 0 c0-.8 .7-1.6 1.9-3 Z" fill="#12BCC9" />
          <circle cx="5" cy="31" r="2" fill="#FFCB3D" />
          <circle cx="24" cy="47" r="7" fill="#1B1A17" /><circle cx="24" cy="47" r="3" fill="#6E6B60" />
          <circle cx="76" cy="47" r="7" fill="#1B1A17" /><circle cx="76" cy="47" r="3" fill="#6E6B60" />
        </g>
      ))}
    </svg>
  );
}

function PaperTruck({ size = 110 }) {
  const h = size * 130 / 200;
  return (
    <svg width={size} height={h} viewBox="0 0 200 130" style={{ filter: 'drop-shadow(0 6px 8px rgba(27,26,23,.18))' }} aria-label="Marco's truck with tools">
      <ellipse cx="100" cy="120" rx="80" ry="6.5" fill="#1B1A17" opacity=".1" />
      {/* bed interior */}
      <polygon points="92,52 184,52 184,74 92,74" fill="#0B838D" />
      {/* tools in the bed */}
      <line x1="102" y1="68" x2="158" y2="14" stroke="#A8A498" strokeWidth="5" strokeLinecap="round" />
      <ellipse cx="163" cy="11" rx="12" ry="8" fill="none" stroke="#0A767F" strokeWidth="4" transform="rotate(-28 163 11)" />
      <path d="M155 8 l14 8 M154 13 l16 2" stroke="#0A767F" strokeWidth="1" opacity=".55" />
      <line x1="120" y1="66" x2="144" y2="22" stroke="#C98E63" strokeWidth="5" strokeLinecap="round" />
      <polygon points="138,20 154,26 149,36 134,29" fill="#FFCB3D" />
      <polygon points="149,36 154,26 156,28 152,38" fill="#E5B22E" />
      <polygon points="96,56 126,56 126,74 96,74" fill="#F2683C" />
      <polygon points="122,56 126,56 126,74 122,74" fill="#D9532B" />
      <path d="M106 56 v-4 h10 v4" stroke="#1B1A17" strokeWidth="2.6" fill="none" strokeLinecap="round" />
      {/* bed rail */}
      <polygon points="88,70 190,70 190,76 88,76" fill="#0A767F" />
      {/* body + rocker */}
      <polygon points="14,74 190,74 190,104 14,104" fill="#12BCC9" />
      <polygon points="92,74 190,74 190,104 92,104" fill="#10A9B5" />
      <polygon points="14,98 190,98 190,104 14,104" fill="#0E98A3" />
      {/* cab */}
      <polygon points="30,46 76,46 90,74 22,74" fill="#12BCC9" />
      <polygon points="30,46 76,46 78,50 28,50" fill="#3ECBD6" />
      <polygon points="38,52 68,52 78,70 34,70" fill="#BFE9FA" />
      <line x1="56" y1="52" x2="60" y2="70" stroke="#12BCC9" strokeWidth="3" />
      {/* door logo */}
      <circle cx="54" cy="86" r="9.5" fill="#FBFAF6" />
      <path d="M54 80.5 c2.4 2.8 3.7 4.3 3.7 6 a3.7 3.7 0 1 1 -7.4 0 c0-1.7 1.3-3.2 3.7-6 Z" fill="#12BCC9" />
      <line x1="66" y1="78" x2="66" y2="96" stroke="#0E98A3" strokeWidth="2" />
      {/* front — grill, bumper, headlight */}
      <polygon points="8,84 14,84 14,104 8,104" fill="#0E98A3" />
      <circle cx="13" cy="81" r="4" fill="#FFCB3D" />
      {/* wheels */}
      <circle cx="52" cy="106" r="14" fill="#1B1A17" /><circle cx="52" cy="106" r="6.5" fill="#6E6B60" /><circle cx="52" cy="106" r="2.4" fill="#A8A498" />
      <circle cx="150" cy="106" r="14" fill="#1B1A17" /><circle cx="150" cy="106" r="6.5" fill="#6E6B60" /><circle cx="150" cy="106" r="2.4" fill="#A8A498" />
    </svg>
  );
}

function PaperHouse({ size = 100 }) {
  const h = size * 150 / 235;
  return (
    <svg width={size} height={h} viewBox="0 0 235 150" style={{ filter: 'drop-shadow(0 6px 8px rgba(27,26,23,.18))' }} aria-label="Emma's home, garden and pool">
      <ellipse cx="116" cy="142" rx="102" ry="6.5" fill="#1B1A17" opacity=".1" />
      {/* chimney */}
      <polygon points="126,28 138,32 138,54 126,50" fill="#A8A498" />
      <polygon points="124,25 140,30 140,34 124,29" fill="#8C8676" />
      {/* walls */}
      <polygon points="100,66 152,80 152,138 100,138" fill="#E8E4D8" />
      <polygon points="28,66 100,66 100,138 28,138" fill="#FBFAF6" />
      {/* roof — front gable + side slope */}
      <polygon points="64,16 116,28 164,78 110,66" fill="#C44E2E" />
      <polygon points="18,66 64,16 110,66" fill="#E2603A" />
      <polygon points="18,66 64,16 110,66 106,70 64,22 22,70" fill="#B8441F" opacity=".35" />
      {/* door + knob */}
      <polygon points="52,100 76,100 76,138 52,138" fill="#FFCB3D" />
      <polygon points="72,100 76,100 76,138 72,138" fill="#E5B22E" />
      <circle cx="69" cy="120" r="1.8" fill="#1B1A17" />
      {/* windows */}
      <rect x="33" y="78" width="15" height="13" fill="#BFE9FA" stroke="#fff" strokeWidth="2.4" />
      <rect x="82" y="78" width="15" height="13" fill="#BFE9FA" stroke="#fff" strokeWidth="2.4" />
      <polygon points="112,92 134,98 134,112 112,106" fill="#9FD0DD" />
      {/* garden — hedge + flower bed */}
      <circle cx="24" cy="133" r="8" fill="#21A84F" /><circle cx="33" cy="136" r="5.5" fill="#1B9647" />
      <ellipse cx="13" cy="138" rx="11" ry="4" fill="#1B9647" />
      <path d="M8 136 v-9 M13 136 v-12 M18 136 v-9" stroke="#21A84F" strokeWidth="1.8" strokeLinecap="round" />
      <circle cx="8" cy="125" r="3" fill="#FFCB3D" /><circle cx="8" cy="125" r="1.1" fill="#E5B22E" />
      <circle cx="13" cy="121" r="3.2" fill="#F2683C" /><circle cx="13" cy="121" r="1.2" fill="#C44E2E" />
      <circle cx="18" cy="125" r="3" fill="#FBFAF6" /><circle cx="18" cy="125" r="1.1" fill="#FFCB3D" />
      <ellipse cx="64" cy="142" rx="14" ry="3" fill="#C9C4B6" />
      {/* pool — deck, water, sheen, waves, ladder, float */}
      <ellipse cx="196" cy="128" rx="37" ry="13.5" fill="#E8E4D8" />
      <ellipse cx="196" cy="127" rx="30" ry="10" fill="#46B6F0" />
      <ellipse cx="192" cy="125" rx="19" ry="5.5" fill="#7FD0F2" opacity=".75" />
      <path d="M180 128 q4 -2.5 8 0 q4 2.5 8 0 M192 131 q4 -2.5 8 0" stroke="#FBFAF6" strokeWidth="1.6" fill="none" strokeLinecap="round" opacity=".85" />
      <path d="M219 118 v9 M224 117 v9 M219 121 h5 M219 125 h5" stroke="#FBFAF6" strokeWidth="2" strokeLinecap="round" />
      <circle cx="206" cy="123" r="4.6" fill="#F2683C" />
      <circle cx="206" cy="123" r="2" fill="#46B6F0" />
    </svg>
  );
}

/* ─── Persona header — the ROLE is the headline; the name is secondary ─ */
const DEMO_PERSONAS = {
  owner: { persona: 'Business owner', name: 'Diego Marta', line: 'runs the book', color: 'var(--green-700)', Person: PaperOwner, Prop: PaperOffice },
  pro:   { persona: 'Pro',            name: 'Marco Ruiz',  line: 'on the route', color: 'var(--blue-700)', Person: PaperPro, Prop: PaperTruck },
  home:  { persona: 'Homeowner',      name: 'Emma Walsh',  line: 'sees it verified', color: 'var(--aqua-700)', Person: PaperHome, Prop: PaperHouse },
};
function PersonaHead({ p }) {
  const m = DEMO_PERSONAS[p];
  const P = m.Person;
  const Prop = m.Prop;
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', gap: 13, padding: '0 6px 8px' }}>
      <span className="pp-hover" style={{ display: 'inline-block', lineHeight: 0 }}><P size={106} /></span>
      <div style={{ paddingBottom: 8, minWidth: 0, flex: 1 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <span style={{ width: 12, height: 12, borderRadius: 4, background: m.color, flexShrink: 0 }} aria-hidden="true" />
          <span style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 26, letterSpacing: '-0.025em', color: 'var(--ink-900)', whiteSpace: 'nowrap', lineHeight: 1 }}>{m.persona}</span>
        </div>
        <div style={{ fontSize: 13, color: 'var(--ink-500)', marginTop: 6, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}><b style={{ color: 'var(--ink-700)' }}>{m.name}</b> · {m.line}</div>
      </div>
      {Prop && <span style={{ lineHeight: 0, flexShrink: 0, marginLeft: 'auto' }} aria-hidden="true"><Prop size={p === 'pro' ? 132 : p === 'home' ? 128 : 134} /></span>}
    </div>
  );
}

/* ─── DmMark — record-mark status (dot + tracked mono), never a pill ── */
const DM_MARK_C = {
  blue:  ['var(--blue-700)', 'var(--blue-500)'],
  aqua:  ['var(--aqua-700)', 'var(--aqua-500)'],
  green: ['var(--green-700)', 'var(--green-600)'],
  yellow:['var(--yellow-700)', 'var(--yellow-500)'],
  alert: ['var(--alert-700)', 'var(--alert-500)'],
  ink:   ['var(--ink-500)', 'var(--ink-300)'],
};
function DmMark({ tone = 'ink', pulse = false, children, style = {} }) {
  const [c, dot] = DM_MARK_C[tone] || DM_MARK_C.ink;
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, flexShrink: 0, whiteSpace: 'nowrap', ...style }}>
      <span className={pulse ? 'tn-pulse' : ''} style={{ width: 8, height: 8, borderRadius: '50%', background: dot, flexShrink: 0 }} />
      <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, fontWeight: 600, letterSpacing: '.12em', color: c }}>{children}</span>
    </span>
  );
}
/* reschedule state → mark */
function rqMark(state, viewer) {
  if (state === 'pending') return viewer === 'owner' ? ['yellow', 'NEEDS YOU', true] : ['yellow', 'PENDING', true];
  if (state === 'proposed') return viewer === 'owner' ? ['yellow', 'WAITING', true] : ['yellow', 'NEW TIME', true];
  if (state === 'approved') return ['green', 'CONFIRMED', false];
  return ['alert', 'DECLINED', false];
}

function DmHint({ children }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 7, fontSize: 11.5, color: 'var(--ink-500)', padding: '7px 2px 0' }}>
      <Icon name="hand" size={13} style={{ color: 'var(--yellow-700)', flexShrink: 0 }} />{children}
    </div>
  );
}

/* ─── Flow trackers — light up as the demo progresses ───────────────── */
function FlowTracker({ label, icon, tone, steps, active = true, onClick }) {
  const toneC = tone === 'aqua' ? 'var(--aqua-700)' : tone === 'blue' ? 'var(--blue-700)' : tone === 'yellow' ? 'var(--yellow-700)' : tone === 'coral' ? 'var(--alert-700)' : tone === 'violet' ? 'var(--chem-violet)' : 'var(--green-700)';
  const tone50 = tone === 'aqua' ? 'var(--aqua-50)' : tone === 'blue' ? 'var(--blue-50)' : tone === 'yellow' ? 'var(--yellow-50)' : tone === 'coral' ? 'var(--alert-50)' : tone === 'violet' ? 'var(--chem-50)' : 'var(--green-50)';
  return (
    <div onClick={onClick} role={onClick ? 'button' : undefined} title={onClick ? `Show the ${label} flow` : undefined} style={{ display: 'flex', alignItems: 'center', gap: 10, background: active ? tone50 : '#fff', border: active ? `1.5px solid ${toneC}` : '1px solid var(--ink-100)', borderRadius: 12, padding: active ? '5.5px 10.5px' : '6px 11px', boxShadow: active ? `0 0 0 3px ${tone50}, var(--shadow-sm)` : 'var(--shadow-sm)', whiteSpace: 'nowrap', flexShrink: 0, cursor: onClick ? 'pointer' : 'default', opacity: active ? 1 : 0.62, transition: 'opacity .15s ease, box-shadow .15s ease' }}>
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontFamily: 'var(--font-mono)', fontSize: 10, fontWeight: 600, letterSpacing: '.1em', color: toneC }}>
        <Icon name={icon} size={14} strokeWidth={2.4} />{label.toUpperCase()}
      </span>
      <span style={{ width: 1, height: 18, background: 'var(--ink-100)' }} />
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 7 }}>
        {steps.map(([lb, done], i) => (
          <span key={lb} style={{ display: 'inline-flex', alignItems: 'center', gap: 7 }}>
            {i > 0 && <Icon name="arrow-right" size={12} style={{ color: 'var(--ink-200)' }} />}
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, fontSize: 12, fontWeight: 700, whiteSpace: 'nowrap', color: done ? toneC : 'var(--ink-400,#A8A498)' }}>
              {done
                ? <span style={{ width: 15, height: 15, borderRadius: '50%', background: toneC, display: 'inline-grid', placeItems: 'center', color: '#fff' }}><Icon name="check" size={9.5} strokeWidth={3.4} /></span>
                : <span style={{ width: 15, height: 15, borderRadius: '50%', border: '2px solid var(--ink-200)', boxSizing: 'border-box' }} />}
              {lb}
            </span>
          </span>
        ))}
      </span>
    </div>
  );
}

/* ─── Sync ticker — every cross-phone event, newest first ───────────── */
const DEMO_TONE = {
  blue:  { bg: 'var(--blue-50)', fg: 'var(--blue-700)' },
  aqua:  { bg: 'var(--aqua-50)', fg: 'var(--aqua-700)' },
  green: { bg: 'var(--green-50)', fg: 'var(--green-700)' },
  yellow:{ bg: 'var(--yellow-50)', fg: 'var(--yellow-700)' },
  alert: { bg: 'var(--alert-50)', fg: 'var(--alert-700)' },
};
const DEMO_P_SHORT = { owner: 'Owner', pro: 'Pro', home: 'Home' };
function SyncTicker({ events }) {
  const list = [...events].reverse();
  return (
    <div style={{ background: 'var(--ink-900)', borderRadius: 18, padding: '11px 16px', display: 'flex', alignItems: 'center', gap: 12, overflow: 'hidden' }}>
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8, flexShrink: 0 }}>
        <span className="tn-pulse" style={{ width: 9, height: 9, borderRadius: '50%', background: 'var(--green-500)' }} />
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10.5, fontWeight: 600, letterSpacing: '.12em', color: 'rgba(255,255,255,.75)', whiteSpace: 'nowrap' }}>LIVE SYNC</span>
      </span>
      <span style={{ width: 1, height: 22, background: 'rgba(255,255,255,.16)', flexShrink: 0 }} />
      {list.length === 0 ? (
        <span style={{ fontSize: 13, color: 'rgba(255,255,255,.55)' }}>One backend, three phones — interact with any phone and watch the others update.</span>
      ) : (
        <div style={{ display: 'flex', gap: 9, overflow: 'hidden', flex: 1, minWidth: 0 }}>
          {list.map((e) => {
            const t = DEMO_TONE[e.tone] || DEMO_TONE.green;
            return (
              <span key={e.id} style={{ display: 'inline-flex', alignItems: 'center', gap: 7, background: 'rgba(255,255,255,.08)', border: '1px solid rgba(255,255,255,.14)', borderRadius: 99, padding: '6px 12px 6px 7px', flexShrink: 0, animation: 'tnSlideUp .3s cubic-bezier(.22,1,.36,1)' }}>
                <span style={{ width: 22, height: 22, borderRadius: '50%', background: t.bg, display: 'grid', placeItems: 'center', color: t.fg }}><Icon name={e.icon} size={12.5} strokeWidth={2.4} /></span>
                <span style={{ fontSize: 12, fontWeight: 600, color: '#fff', whiteSpace: 'nowrap' }}>{e.msg}</span>
                <span style={{ fontFamily: 'var(--font-mono)', fontSize: 9, letterSpacing: '.06em', color: 'rgba(255,255,255,.55)', whiteSpace: 'nowrap' }}>→ {e.to.map(p => DEMO_P_SHORT[p]).join(' + ')}</span>
              </span>
            );
          })}
        </div>
      )}
    </div>
  );
}

/* ─── Demo bell + in-phone notification sheet ───────────────────────── */
function DemoBell({ persona, world, act }) {
  const mine = world.events.filter(e => e.to.includes(persona));
  const unread = Math.max(0, mine.length - world.read[persona]);
  return <NotifBell count={unread} size={42} onClick={() => act.openNotifs(persona)} />;
}
function DemoNotifSheet({ persona, world, act }) {
  const mine = [...world.events.filter(e => e.to.includes(persona))].reverse();
  return (
    <Sheet open={world.notifOpen === persona} onClose={() => act.closeNotifs(persona)} title="Notifications">
      {mine.length === 0 ? (
        <div style={{ textAlign: 'center', padding: '18px 0 10px' }}>
          {persona === 'owner' ? <Sprout size={88} mood="zzz" /> : <Dewy size={88} mood="zzz" />}
          <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 15, marginTop: 6 }}>All quiet.</div>
          <div style={{ fontSize: 12.5, color: 'var(--ink-500)', marginTop: 3 }}>When something happens on the other phones, it shows up here.</div>
        </div>
      ) : (
        <div className="card" style={{ overflow: 'hidden' }}>
          {mine.map((e, i) => {
            const t = DEMO_TONE[e.tone] || DEMO_TONE.green;
            return (
              <div key={e.id} style={{ display: 'flex', gap: 11, padding: '12px 13px', borderTop: i ? '1px solid var(--ink-100)' : 'none' }}>
                <span style={{ width: 36, height: 36, borderRadius: 10, background: t.bg, display: 'grid', placeItems: 'center', color: t.fg, flexShrink: 0 }}><Icon name={e.icon} size={18} strokeWidth={2.2} /></span>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontWeight: 700, fontSize: 13 }}>{e.msg}</div>
                  <div style={{ fontFamily: 'var(--font-mono)', fontSize: 9.5, color: 'var(--ink-400,#A8A498)', marginTop: 2 }}>{e.at}</div>
                </div>
              </div>
            );
          })}
        </div>
      )}
    </Sheet>
  );
}

/* ─── PaperScene — depth-of-field papercraft diorama behind the phones ──
   Three depth layers (blurred far → crisp near): paper hills + sun +
   clouds at the back; Emma's house and a paper tree mid; Marco's Mowdew
   truck (gap 1) and the pool (gap 2) up front. Coordinates match the
   1800-wide demo stage; the phones occlude the middle of each element,
   which is what sells the depth. Decorative only — aria-hidden.          */
function PaperScene() {
  const sh = (blur = 0) => ({ filter: `${blur ? `blur(${blur}px) ` : ''}drop-shadow(0 6px 8px rgba(27,26,23,.14))` });
  return (
    <div aria-hidden="true" style={{ position: 'absolute', left: -24, right: -24, top: -36, bottom: -8, pointerEvents: 'none', zIndex: 0 }}>
      <svg width="100%" height="100%" viewBox="0 0 1800 1000" preserveAspectRatio="none">
        {/* ── FAR: sun, clouds, back hills (soft blur = depth) ── */}
        <g style={sh(2.2)} opacity=".9">
          <circle cx="1714" cy="84" r="34" fill="#FFCB3D" />
          <polygon points="1714,50 1722,68 1714,84 1706,68" fill="#FFE08A" opacity=".8" />
          <path d="M40 110 q14 -26 44 -22 q10 -20 36 -14 q24 4 26 24 q22 2 18 20 l-118 0 Z" fill="#FFFFFF" opacity=".92" />
          <path d="M1062 52 q12 -22 38 -19 q9 -17 31 -12 q21 4 22 21 q19 2 16 17 l-102 0 Z" fill="#FFFFFF" opacity=".85" />
          <path d="M0 800 Q 150 742 330 786 Q 520 826 700 778 Q 900 736 1100 784 Q 1300 826 1500 776 Q 1650 744 1800 788 L 1800 1000 L 0 1000 Z" fill="#E4F0DA" />
        </g>
        {/* ── MID: mid hills, Emma's house (right), paper tree (left) ── */}
        <g style={sh(0.9)}>
          <path d="M0 868 Q 200 822 420 858 Q 640 892 880 850 Q 1120 814 1340 856 Q 1560 894 1800 848 L 1800 1000 L 0 1000 Z" fill="#D3E8C7" />
          {/* house */}
          <g>
            <polygon points="1632,866 1632,962 1762,962 1762,866" fill="#FBF3DD" />
            <polygon points="1717,866 1762,866 1762,962 1717,962" fill="#EFE0BD" />
            <polygon points="1620,872 1697,806 1774,872" fill="#FFCB3D" />
            <polygon points="1697,806 1774,872 1746,872 1697,830" fill="#E5B22E" />
            <polygon points="1726,816 1740,816 1740,842 1726,842" fill="#C9705A" />
            <polygon points="1672,910 1700,910 1700,962 1672,962" fill="#21A84F" />
            <circle cx="1696" cy="936" r="2.4" fill="#FFCB3D" />
            <polygon points="1644,896 1664,896 1664,918 1644,918" fill="#9BD7F2" />
            <polygon points="1712,896 1732,896 1732,918 1712,918" fill="#9BD7F2" />
            <path d="M1644 907 h20 M1654 896 v22 M1712 907 h20 M1722 896 v22" stroke="#FBF3DD" strokeWidth="2" />
            <ellipse cx="1652" cy="964" rx="16" ry="9" fill="#6FBE6A" />
          </g>
          {/* paper tree + bush, left margin */}
          <g>
            <polygon points="84,962 80,886 100,886 96,962" fill="#9A6B45" />
            <polygon points="90,886 100,886 96,962 90,962" fill="#7E5536" />
            <circle cx="68" cy="864" r="30" fill="#5FB45D" />
            <circle cx="112" cy="850" r="36" fill="#6FBE6A" />
            <circle cx="88" cy="824" r="30" fill="#83CB7C" />
            <polygon points="112,818 132,842 116,850" fill="#8FD487" opacity=".8" />
            <ellipse cx="138" cy="958" rx="22" ry="12" fill="#6FBE6A" />
            <ellipse cx="148" cy="952" rx="12" ry="8" fill="#83CB7C" />
          </g>
        </g>
        {/* ── NEAR: front hill, Marco's truck (gap 1), the pool (gap 2) ── */}
        <g style={sh()}>
          <path d="M0 940 Q 240 906 480 934 Q 760 964 1040 930 Q 1320 902 1800 938 L 1800 1000 L 0 1000 Z" fill="#C2DFB4" />
          {/* Mowdew truck — side view, nose into the gap */}
          <g>
            <ellipse cx="630" cy="972" rx="120" ry="9" fill="#1B1A17" opacity=".12" />
            {/* gear in the bed */}
            <polygon points="688,872 694,872 678,918 672,918" fill="#A8A498" />
            <ellipse cx="694" cy="868" rx="9" ry="6" fill="none" stroke="#0A767F" strokeWidth="3" transform="rotate(-28 694 868)" />
            <polygon points="712,884 717,884 706,918 701,918" fill="#C9705A" />
            {/* bed + cab */}
            <polygon points="540,900 540,952 742,952 742,900" fill="#21A84F" />
            <polygon points="640,900 742,900 742,952 640,952" fill="#178A40" />
            <polygon points="742,914 742,952 706,952 706,914" fill="#15803C" opacity="0" />
            <polygon points="540,900 540,862 600,862 622,900" fill="#21A84F" />
            <polygon points="548,868 594,868 610,896 548,896" fill="#9BD7F2" />
            <polygon points="578,868 594,868 610,896 578,896" fill="#7CC4E8" />
            {/* bumper + lights */}
            <polygon points="528,932 540,928 540,952 528,950" fill="#D9D4C8" />
            <circle cx="535" cy="924" r="4" fill="#FFCB3D" />
            {/* door + logo */}
            <path d="M624 902 v48" stroke="#15803C" strokeWidth="2.5" />
            <circle cx="592" cy="922" r="13" fill="#FBFAF6" />
            <path d="M592 913 c3.4 4 5.2 6.2 5.2 8.6 a5.2 5.2 0 1 1 -10.4 0 c0-2.4 1.8-4.6 5.2-8.6 Z" fill="#12BCC9" />
            {/* wheels */}
            <circle cx="582" cy="954" r="17" fill="#1B1A17" /><circle cx="582" cy="954" r="8" fill="#D9D4C8" />
            <circle cx="700" cy="954" r="17" fill="#1B1A17" /><circle cx="700" cy="954" r="8" fill="#D9D4C8" />
          </g>
          {/* the pool — paper deck, faceted water, ladder, ring float */}
          <g>
            <ellipse cx="1172" cy="938" rx="118" ry="42" fill="#EFE7D0" />
            <ellipse cx="1172" cy="934" rx="118" ry="42" fill="#F7F1DF" />
            <ellipse cx="1172" cy="936" rx="96" ry="32" fill="#46B6F0" />
            <ellipse cx="1172" cy="934" rx="96" ry="32" fill="#5BC8E8" />
            <path d="M1090 934 q20 -12 42 0 q22 12 44 0 q22 -12 44 0" stroke="#9BE2F5" strokeWidth="5" fill="none" strokeLinecap="round" />
            <path d="M1106 946 q18 -10 38 0 q20 10 40 0 q20 -10 40 0" stroke="#8ADDF2" strokeWidth="4" fill="none" strokeLinecap="round" opacity=".8" />
            {/* ladder */}
            <path d="M1238 904 v34 M1252 904 v32" stroke="#FBFAF6" strokeWidth="4.5" strokeLinecap="round" />
            <path d="M1238 912 h14 M1238 922 h14" stroke="#FBFAF6" strokeWidth="3.5" strokeLinecap="round" />
            {/* sun ring float */}
            <ellipse cx="1130" cy="940" rx="17" ry="9" fill="#FFCB3D" />
            <ellipse cx="1130" cy="939" rx="8" ry="4" fill="#5BC8E8" />
            {/* bush */}
            <ellipse cx="1072" cy="962" rx="18" ry="10" fill="#6FBE6A" />
          </g>
        </g>
      </svg>
    </div>
  );
}

/* ─── CrayonHint — hand-drawn note that sits in the gutter BESIDE a phone and
   points at it. dir='left' = phone is to the LEFT (note in the right gutter);
   dir='right' = phone is to the RIGHT (note in the left gutter). The note is
   anchored fully outside the phone so it never overlaps the screen.          ─ */
function CrayonHint({ text, tone, idx = 0, dir = 'left', base = 240 }) {
  const isLeft = dir === 'left';              // phone is to the LEFT of the note
  const pos = isLeft ? { left: '100%', marginLeft: 8 } : { right: '100%', marginRight: 8 };
  const Arrow = (
    <svg className="pp-hint-arrow" width="34" height="22" viewBox="0 0 34 22" fill="none" aria-hidden="true"
      style={{ flexShrink: 0, transform: isLeft ? 'none' : 'scaleX(-1)' }}>
      {/* points LEFT toward the phone; flipped for the right-gutter notes */}
      <path d="M32 7 C24 7 15 10 4 15" stroke={tone} strokeWidth="4" strokeLinecap="round" opacity=".92" />
      <path d="M12 9.5 L3 15 L11.5 19.5" stroke={tone} strokeWidth="4" strokeLinecap="round" strokeLinejoin="round" opacity=".92" />
    </svg>
  );
  const Note = (
    <span style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 15, fontStyle: 'italic', letterSpacing: '-0.01em', color: tone, background: 'rgba(251,250,246,.97)', border: '1.5px dashed ' + tone, borderRadius: 12, padding: '6px 13px', whiteSpace: 'nowrap', boxShadow: 'var(--shadow-md)' }}>{text}</span>
  );
  return (
    <div className="pp-hint" style={{ position: 'absolute', top: base + idx * 50, zIndex: 6, display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 6, pointerEvents: 'none', width: 'max-content', ...pos }}>
      {isLeft ? <>{Arrow}{Note}</> : <>{Note}{Arrow}</>}
    </div>
  );
}

Object.assign(window, {
  dmClock, PaperOwner, PaperPro, PaperHome, PaperAvatar, PaperOffice, PaperTruck, PaperHouse, DEMO_PERSONAS, PersonaHead, CrayonHint,
  DmMark, rqMark, DmHint, FlowTracker, SyncTicker, DEMO_TONE, DemoBell, DemoNotifSheet, PaperScene,
});
