/* ============================================================
   STORYBOOK v7 — part 2

   Fig 4 (A6_AutoprinterRouting):
   - Reverted to v4 layout: order context (left) → routing rules
     (middle) → template pools (top right) → two print stations
     (bottom right). Animated docs travel template → routing →
     destination printer (different printers per rule).
   - Printer art inside stations replaced with V2-style mini
     printers (squat thermal w/ rounded top, slanted-feed doc).

   Fig 5 (A6_DesktopUtility):
   - Reverted to v4 layout: laptop center, thermal printer LEFT,
     document printer RIGHT. Flying-in label + slip from off-
     screen near the LABEL JOB IN / DOCUMENT JOB IN labels.
   - Lines from the IN labels to the laptop REMOVED (the flying
     papers tell the story).
   - Laptop slightly smaller. Bigger IN labels.
   - V2 printer art, but the printer's own output is animated
     IN-PLACE (no tiny strips floating away).

   Depends on scene-utils.jsx + APMarkV5 from v5-1.
   ============================================================ */


/* ------------------------------------------------------------
   Reusable mini V2 printer art (used inside print station boxes
   on Fig 4). Full-bodied, no separate emerging strips.
------------------------------------------------------------ */
const V5MiniThermal = ({ x = 0, y = 0, scale = 1, animate = false, blink = "0s" }) => (
  <g transform={`translate(${x}, ${y}) scale(${scale})`}>
    {/* spool/curved top */}
    <path d="M 4 22 Q 50 -2 96 22 L 96 60 L 4 60 Z" fill={PALETTE.ink} stroke={PALETTE.ink} strokeWidth="1.2"/>
    {/* exit slot */}
    <rect x="14" y="34" width="72" height="3" fill={PALETTE.paper}/>
    {/* status LED */}
    <circle cx="84" cy="46" r="2.6" fill={PALETTE.honey}>
      {animate && <animate attributeName="opacity" values="1;0.4;1" dur="1.4s" repeatCount="indefinite" begin={blink}/>}
    </circle>
    {/* small screen */}
    <rect x="14" y="42" width="14" height="8" rx="1.5" fill={PALETTE.paper3}/>
    {/* feet */}
    <rect x="10" y="60" width="10" height="4" fill={PALETTE.ink3}/>
    <rect x="80" y="60" width="10" height="4" fill={PALETTE.ink3}/>
  </g>
);

const V5MiniDoc = ({ x = 0, y = 0, scale = 1, animate = false, blink = "0.4s" }) => (
  <g transform={`translate(${x}, ${y}) scale(${scale})`}>
    {/* slanted top output tray */}
    <path d="M 14 -2 L 86 -2 L 80 14 L 20 14 Z" fill={PALETTE.paper3} stroke={PALETTE.ink} strokeWidth="1"/>
    {/* main body */}
    <path d="M 8 14 L 92 14 L 100 26 L 100 64 L 0 64 L 0 26 Z" fill={PALETTE.paper2} stroke={PALETTE.ink} strokeWidth="1.2" strokeLinejoin="round"/>
    {/* control screen */}
    <rect x="62" y="32" width="30" height="14" rx="2" fill={PALETTE.ink}/>
    <rect x="66" y="36" width="22" height="2" rx="1" fill={PALETTE.honey}/>
    <rect x="66" y="40" width="14" height="1.5" rx="0.5" fill={PALETTE.ink5}/>
    {/* output slot */}
    <rect x="14" y="22" width="60" height="2" fill={PALETTE.ink}/>
    {/* status LED */}
    <circle cx="92" cy="50" r="2.4" fill={PALETTE.ok}>
      {animate && <animate attributeName="opacity" values="1;0.4;1" dur="1.4s" repeatCount="indefinite" begin={blink}/>}
    </circle>
    {/* feet */}
    <rect x="6" y="64" width="10" height="4" fill={PALETTE.ink3}/>
    <rect x="84" y="64" width="10" height="4" fill={PALETTE.ink3}/>
  </g>
);


/* ------------------------------------------------------------
   A6_AutoprinterRouting — REVERT TO V4 LAYOUT
   Order context → Routing Rules → Template Pools → Stations.
   Animated docs traverse the full path AND end at different
   printers depending on the rule (warehouse · doc + packing
   room · thermal).
------------------------------------------------------------ */
const A7_SlideLabel = ({ num, title, body, show }) => {
  if (!show) return null;
  return (
    <g>
      <text x="980" y="32" fontFamily="Geist Mono, monospace" fontSize="11" fill={PALETTE.honeyDk}
            textAnchor="end" fontWeight="700" letterSpacing="0.18em">{num}</text>
      <text x="980" y="52" fontFamily="Geist, sans-serif" fontSize="20" fill={PALETTE.ink}
            textAnchor="end" fontWeight="500" letterSpacing="-0.01em">{title}</text>
      <foreignObject x="600" y="58" width="380" height="60">
        <div xmlns="http://www.w3.org/1999/xhtml"
             style={{fontFamily:"'Geist', sans-serif", fontSize:"12px", color:PALETTE.ink3,
                     lineHeight:"1.45", textAlign:"right"}}>
          {body}
        </div>
      </foreignObject>
    </g>
  );
};

const A6_AutoprinterRouting = ({ motion = true, annotated = true, showLabels = true, staticPose = false }) => {
  const W = 1000, H = 600;
  const animate = motion && !staticPose;
  return (
    <div style={{ width: "100%", aspectRatio: `${W} / ${H}` }}>
      <svg viewBox={`0 0 ${W} ${H}`} width="100%" height="100%" style={{ display: "block", overflow: "visible" }}>
        <defs>
          <linearGradient id="a6-3-bg" x1="0" x2="0" y1="0" y2="1">
            <stop offset="0" stopColor={PALETTE.paper}/><stop offset="1" stopColor={PALETTE.paper2}/>
          </linearGradient>
        </defs>
        <rect width={W} height={H} fill="url(#a6-3-bg)"/>


        {showLabels && (
          <Tag x={40} y={36} text="03 · AUTOPRINTER ROUTING" color={PALETTE.honeyDk} size={14} weight={600}/>
        )}

        {/* MERGED ROUTING ENGINE — order context (left) + routing rules (right) in one box.
            Order rows align 1:1 with rule rows so the trigger arrows read horizontally. */}
        <g transform="translate(90, 200)">
          {/* outer dark body */}
          <rect x="0" y="0" width="360" height="220" rx="10" fill={PALETTE.ink} stroke={PALETTE.ink} strokeWidth="1.4"/>
          {/* unified honey header */}
          <rect x="0" y="0" width="360" height="28" rx="10" fill={PALETTE.honey}/>
          <rect x="0" y="20" width="360" height="8" fill={PALETTE.honey}/>
          {/* subtle divider between the two halves of the header */}
          <line x1="170" y1="6" x2="170" y2="22" stroke={PALETTE.ink} strokeWidth="0.8" opacity="0.35"/>
          <text x="85" y="20" fontFamily="Geist Mono, monospace" fontSize="10" fill={PALETTE.ink} textAnchor="middle" letterSpacing="0.16em" fontWeight="700">ORDER #1042</text>
          <text x="270" y="20" fontFamily="Geist Mono, monospace" fontSize="10" fill={PALETTE.ink} textAnchor="middle" letterSpacing="0.16em" fontWeight="700">PRINT RULES</text>

          {/* ORDER FIELDS — left column, 4 rows aligned 1:1 with rule rows */}
          <g transform="translate(10, 40)">
            {[
              ["tags", "wholesale, priority"],
              ["source", "Online Store"],
              ["items", "4"],
              ["weight", "2.1 lb"],
            ].map(([label, value], i) => (
              <g key={i} transform={`translate(0, ${i * 40})`}>
                <rect x="0" y="0" width="140" height="34" rx="3" fill={PALETTE.ink2} stroke={PALETTE.ink3} strokeWidth="0.6"/>
                <text x="8" y="14" fontFamily="Geist Mono, monospace" fontSize="8" fill={PALETTE.ink5} letterSpacing="0.06em">{label}</text>
                <text x="8" y="27" fontFamily="Geist Mono, monospace" fontSize="9" fill={PALETTE.paper} fontWeight="700">{value}</text>
              </g>
            ))}
          </g>

          {/* ROUTING RULES — right column. Rules 1 and 3 fire (highlight in sync); 2 and 4 stay dark. */}
          <g transform="translate(180, 40)">
            {[
              ["if tag = wholesale", "→ INV-NET30 · WAREHOUSE"],
              ["if source = Amazon", "→ SLIP-AMZN · WAREHOUSE"],
              ["if items > 3", "→ Pack Slip · PACKING ROOM"],
              ["if weight > 5 lb", "→ BIG-LABEL · WAREHOUSE"],
            ].map(([cond, eff], i) => {
              const fires = i === 0 || i === 2;
              return (
                <g key={i} transform={`translate(0, ${i * 40})`}>
                  <rect x="0" y="0" width="180" height="34" rx="3" fill={PALETTE.ink2} stroke={PALETTE.ink3} strokeWidth="0.6"/>
                  <text x="8" y="14" fontFamily="Geist Mono, monospace" fontSize="8" fill={PALETTE.ink5} letterSpacing="0.06em">{cond}</text>
                  <text x="8" y="27" fontFamily="Geist Mono, monospace" fontSize="8" fill={PALETTE.honey} fontWeight="700">{eff}</text>
                  {((animate || staticPose) && fires) && (
                    <rect x="-2" y="-2" width="184" height="38" rx="3" fill="none" stroke={PALETTE.honey} strokeWidth="1.4" opacity={staticPose ? "1" : "0"}>
                      {animate && <animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.06;0.18;0.85;0.92;1" dur="6s" repeatCount="indefinite"/>}
                    </rect>
                  )}
                </g>
              );
            })}
          </g>

          {/* INTRA-BOX TRIGGER ARROWS — order field → firing rule.
              Tags row (i=0) center y = 40 + 17 = 57 → Rule 1 left edge (x=180).
              Items row (i=2) center y = 40 + 80 + 17 = 137 → Rule 3 left edge (x=180). */}
          <g stroke={PALETTE.honeyLn} strokeWidth="1.3" fill="none" strokeDasharray="3 2" strokeLinecap="round">
            <path d="M 150 57 L 178 57"/>
            <path d="M 178 57 L 173 54 M 178 57 L 173 60"/>
            <path d="M 150 137 L 178 137"/>
            <path d="M 178 137 L 173 134 M 178 137 L 173 140"/>
          </g>
        </g>

        {/* INVOICE template pool */}
        <g transform="translate(540, 70)">
          <rect x="0" y="0" width="170" height="120" rx="6" fill={PALETTE.paper3} stroke={PALETTE.ink} strokeWidth="1.2"/>
          <Tag x={10} y={18} text="INVOICE TEMPLATES" color={PALETTE.honeyDk} size={9} weight={600}/>
          <g transform="translate(14, 28)">
            {[0,1,2].map((i) => (
              <g key={i} transform={`translate(${i * 46}, ${i * 4})`}>
                <rect x="0" y="0" width="40" height="56" rx="2" fill={PALETTE.paper} stroke={PALETTE.ink} strokeWidth="0.8"/>
                <rect x="4" y="6" width="20" height="2" fill={PALETTE.ink}/>
                {[12,16,20,24,28].map((y, j) => <rect key={j} x="4" y={y} width={[26,22,24,18,20][j]} height="1" fill={PALETTE.ink5}/>)}
                <text x="20" y="50" fontFamily="Geist Mono, monospace" fontSize="5" fill={PALETTE.ink3} textAnchor="middle">{["DEFAULT","NET30","INTL"][i]}</text>
                {((animate || staticPose) && i === 1) && (
                  <rect x="-2" y="-2" width="44" height="60" rx="2" fill="none" stroke={PALETTE.honey} strokeWidth="1.6" opacity={staticPose ? "1" : "0"}>
                    {animate && <animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.10;0.14;0.20;0.24;1" dur="6s" repeatCount="indefinite"/>}
                  </rect>
                )}
              </g>
            ))}
          </g>
        </g>

        {/* SLIP template pool */}
        <g transform="translate(740, 70)">
          <rect x="0" y="0" width="170" height="120" rx="6" fill={PALETTE.paper3} stroke={PALETTE.ink} strokeWidth="1.2"/>
          <Tag x={10} y={18} text="PACKING SLIP TEMPLATES" color={PALETTE.honeyDk} size={9} weight={600}/>
          <g transform="translate(14, 28)">
            {[0,1,2].map((i) => (
              <g key={i} transform={`translate(${i * 46}, ${i * 4})`}>
                <rect x="0" y="0" width="40" height="56" rx="2" fill={PALETTE.paper} stroke={PALETTE.ink} strokeWidth="0.8"/>
                <rect x="4" y="6" width="22" height="2" fill={PALETTE.ink}/>
                {[12,16,20,24,28,32].map((y, j) => <rect key={j} x="4" y={y} width={[24,28,20,26,16,22][j]} height="1" fill={PALETTE.ink5}/>)}
                <g transform="translate(4, 38)">
                  {[0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32].map((x, j) => (
                    <rect key={j} x={x} y="0" width={j % 2 === 0 ? 1 : 0.6} height="6" fill={PALETTE.ink}/>
                  ))}
                </g>
                <text x="20" y="52" fontFamily="Geist Mono, monospace" fontSize="5" fill={PALETTE.ink3} textAnchor="middle">{["MIN","PACK","UPS"][i]}</text>
                {((animate || staticPose) && i === 1) && (
                  <rect x="-2" y="-2" width="44" height="60" rx="2" fill="none" stroke={PALETTE.honey} strokeWidth="1.6" opacity={staticPose ? "1" : "0"}>
                    {animate && <animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.32;0.36;0.42;0.46;1" dur="6s" repeatCount="indefinite"/>}
                  </rect>
                )}
              </g>
            ))}
          </g>
        </g>

        {/* PRINT STATIONS — bottom right (warehouse active, packing room active too) */}
        <g transform="translate(540, 420)">
          <rect x="-2" y="2" width="180" height="160" rx="6" fill={PALETTE.ink} opacity="0.10"/>
          <rect x="0" y="0" width="180" height="160" rx="6" fill={PALETTE.paper3} stroke={PALETTE.ink} strokeWidth="1.4"/>
          <rect x="0" y="0" width="180" height="22" rx="6" fill={PALETTE.honeySf}/>
          <rect x="0" y="14" width="180" height="8" fill={PALETTE.honeySf}/>
          <Tag x={10} y={15} text="PACKING ROOM STATION" color={PALETTE.honeyDk} size={9} weight={700}/>
          <V5MiniThermal x={6} y={42} scale={0.7} animate={animate} blink="0s"/>
          <V5MiniDoc x={94} y={42} scale={0.7} animate={animate} blink="0.4s"/>
          <text x="40" y="120" fontFamily="Geist Mono, monospace" fontSize="7" fill={PALETTE.ink3} textAnchor="middle" fontWeight="600">THERMAL</text>
          <text x="128" y="120" fontFamily="Geist Mono, monospace" fontSize="7" fill={PALETTE.ink3} textAnchor="middle" fontWeight="600">DOCUMENT</text>
          <text x="90" y="138" fontFamily="Geist Mono, monospace" fontSize="8" fill={PALETTE.ink4} textAnchor="middle" letterSpacing="0.08em">queens · pack-out</text>
          <g transform="translate(90, 152)">
            <circle cx="0" cy="0" r="4" fill={PALETTE.ok}>
              {animate && <animate attributeName="opacity" values="1;0.4;1" dur="1.6s" repeatCount="indefinite"/>}
            </circle>
            <text x="10" y="3" fontFamily="Geist Mono, monospace" fontSize="8" fill={PALETTE.ok} fontWeight="700">ONLINE</text>
          </g>
          {(animate || staticPose) && (
            <rect x="-3" y="-3" width="186" height="166" rx="6" fill="none" stroke={PALETTE.honey} strokeWidth="2" opacity={staticPose ? "1" : "0"}>
              {animate && <animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.71;0.75;0.90;0.95;1" dur="6s" repeatCount="indefinite"/>}
            </rect>
          )}
        </g>

        <g transform="translate(740, 420)">
          <rect x="-2" y="2" width="180" height="160" rx="6" fill={PALETTE.ink} opacity="0.10"/>
          <rect x="0" y="0" width="180" height="160" rx="6" fill={PALETTE.paper3} stroke={PALETTE.ink} strokeWidth="1.4"/>
          <rect x="0" y="0" width="180" height="22" rx="6" fill={PALETTE.honeySf}/>
          <rect x="0" y="14" width="180" height="8" fill={PALETTE.honeySf}/>
          <Tag x={10} y={15} text="WAREHOUSE STATION" color={PALETTE.honeyDk} size={9} weight={700}/>
          <V5MiniThermal x={6} y={42} scale={0.7} animate={animate} blink="0.8s"/>
          <V5MiniDoc x={94} y={42} scale={0.7} animate={animate} blink="1.2s"/>
          <text x="40" y="120" fontFamily="Geist Mono, monospace" fontSize="7" fill={PALETTE.ink3} textAnchor="middle" fontWeight="600">THERMAL</text>
          <text x="128" y="120" fontFamily="Geist Mono, monospace" fontSize="7" fill={PALETTE.ink3} textAnchor="middle" fontWeight="600">DOCUMENT</text>
          <text x="90" y="138" fontFamily="Geist Mono, monospace" fontSize="8" fill={PALETTE.ink4} textAnchor="middle" letterSpacing="0.08em">brooklyn · usps</text>
          <g transform="translate(90, 152)">
            <circle cx="0" cy="0" r="4" fill={PALETTE.ok}>
              {animate && <animate attributeName="opacity" values="1;0.4;1" dur="1.6s" repeatCount="indefinite" begin="0.6s"/>}
            </circle>
            <text x="10" y="3" fontFamily="Geist Mono, monospace" fontSize="8" fill={PALETTE.ok} fontWeight="700">ONLINE</text>
          </g>
          {(animate || staticPose) && (
            <rect x="-3" y="-3" width="186" height="166" rx="6" fill="none" stroke={PALETTE.honey} strokeWidth="2" opacity={staticPose ? "1" : "0"}>
              {animate && <animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.46;0.50;0.65;0.70;1" dur="6s" repeatCount="indefinite"/>}
            </rect>
          )}
        </g>

        {/* Connecting lines — anchored to FIRING-RULE row middles so each firing rule
            has one inbound (from its template pool) + one outbound (to its station) line
            meeting at its right edge. Some crossover between C and D is intentional.
            Rule 1 row middle right edge: (450, 257). Rule 3 row middle right edge: (450, 337).
            A/B (rules → templates) curved; C/D (rules → stations) straight.
            All strokeWidth 1.6.
            Templates lines (A, B): dashes flow templates → rules (positive offset).
            Stations lines  (C, D): dashes flow rules → stations (negative offset). */}
        <g stroke={PALETTE.honeyLn} strokeWidth="1.6" fill="none" strokeDasharray="3 3" opacity="0.7">
          {/* A — Rule 1 ↔ INV pool */}
          <path d="M 450 257 Q 540 215 600 190">
            {animate && <animate attributeName="stroke-dashoffset" from="0" to="32" dur="1.6s" repeatCount="indefinite"/>}
          </path>
          {/* B — Rule 3 ↔ SLIP pool */}
          <path d="M 450 337 Q 620 250 800 190">
            {animate && <animate attributeName="stroke-dashoffset" from="0" to="32" dur="1.6s" repeatCount="indefinite" begin="0.4s"/>}
          </path>
          {/* C — Rule 1 (INV-NET30) → PACKING ROOM station (lands at top-edge center) */}
          <path d="M 450 257 L 830 420">
            {animate && <animate attributeName="stroke-dashoffset" from="0" to="-32" dur="1.6s" repeatCount="indefinite"/>}
          </path>
          {/* D — Rule 3 (PACKLIST) → WAREHOUSE station (lands at top-edge center) */}
          <path d="M 450 337 L 630 420">
            {animate && <animate attributeName="stroke-dashoffset" from="0" to="-32" dur="1.6s" repeatCount="indefinite" begin="0.4s"/>}
          </path>
        </g>

        {/* ANIMATED DOCUMENTS — template → 5% pause at firing rule's right edge → printer.
            Invoice (rule 1, INV-NET30) → Packing Room · Document.
            Slip    (rule 3, PACKLIST)  → Warehouse · Document.
            In static pose, both freeze at their firing rule's right edge
            (the dwell-position in the animation). */}
        {(animate || staticPose) && (
          <>
            {/* INVOICE traveler — invoice template (605, 110) → rule 1 right edge (450, 257) → pack-room doc printer (828, 460) */}
            <g transform={staticPose ? "translate(450, 257)" : undefined}>
              {animate && (
                <animateTransform attributeName="transform" type="translate"
                                  values="605 110; 605 110; 450 257; 450 257; 828 460; 828 460; 828 460; 828 460"
                                  keyTimes="0; 0.18; 0.30; 0.35; 0.50; 0.85; 0.90; 1" dur="6s" repeatCount="indefinite"/>
              )}
              <g transform="translate(-20, -26)" opacity={staticPose ? "1" : "0"}>
                {animate && <animate attributeName="opacity" values="0;0;1;1;1;1;0;0" keyTimes="0;0.18;0.30;0.35;0.50;0.85;0.90;1" dur="6s" repeatCount="indefinite"/>}
                <rect x="0" y="0" width="40" height="52" rx="2" fill={PALETTE.paper} stroke={PALETTE.ink} strokeWidth="1"/>
                <rect x="4" y="6" width="20" height="2" fill={PALETTE.ink}/>
                {[12,16,20,24,28].map((y, j) => <rect key={j} x="4" y={y} width={[24,20,22,16,18][j]} height="1" fill={PALETTE.ink5}/>)}
                <text x="20" y="46" fontFamily="Geist Mono, monospace" fontSize="5" fill={PALETTE.ink3} textAnchor="middle">INV · NET30</text>
                <Face cx={32} cy={6} r={3.5}/>
              </g>
            </g>

            {/* SLIP traveler — slip template (805, 110) → rule 3 right edge (450, 337) → warehouse doc printer (628, 460) */}
            <g transform={staticPose ? "translate(450, 337)" : undefined}>
              {animate && (
                <animateTransform attributeName="transform" type="translate"
                                  values="805 110; 805 110; 450 337; 450 337; 628 460; 628 460; 628 460; 628 460"
                                  keyTimes="0; 0.40; 0.55; 0.60; 0.75; 0.92; 0.97; 1" dur="6s" repeatCount="indefinite"/>
              )}
              <g transform="translate(-20, -26)" opacity={staticPose ? "1" : "0"}>
                {animate && <animate attributeName="opacity" values="0;0;1;1;1;1;0;0" keyTimes="0;0.40;0.55;0.60;0.75;0.92;0.97;1" dur="6s" repeatCount="indefinite"/>}
                <rect x="0" y="0" width="40" height="52" rx="2" fill={PALETTE.paper} stroke={PALETTE.ink} strokeWidth="1"/>
                <rect x="4" y="6" width="22" height="2" fill={PALETTE.ink}/>
                {[12,16,20,24,28,32].map((y, j) => <rect key={j} x="4" y={y} width={[20,24,18,22,14,18][j]} height="1" fill={PALETTE.ink5}/>)}
                <text x="20" y="48" fontFamily="Geist Mono, monospace" fontSize="5" fill={PALETTE.ink3} textAnchor="middle">Pack Slip</text>
              </g>
            </g>
          </>
        )}

        {annotated && (
          <>
            <Annotation x={40} y={130} label="3.1 · ORDER CONTEXT" body="Order context determines which Print Rule to trigger"/>
          </>
        )}

        {/* 3.2 step text — right side, between template pools (top) and print stations (bottom) */}
        <g>
          <text x="980" y="310" fontFamily="Geist Mono, monospace" fontSize="11" fill={PALETTE.honeyDk}
                textAnchor="end" fontWeight="700" letterSpacing="0.14em">3.2 · PRINT RULE FIRES</text>
          <text x="980" y="326" fontFamily="Geist, sans-serif" fontSize="11" fill={PALETTE.ink4}
                textAnchor="end">Print Rule selects the template and</text>
          <text x="980" y="341" fontFamily="Geist, sans-serif" fontSize="11" fill={PALETTE.ink4}
                textAnchor="end">routes to the appropriate printer.</text>
        </g>
      </svg>
    </div>
  );
};


/* ------------------------------------------------------------
   A6_DesktopUtility — REVERT TO V4 LAYOUT
   - Laptop center (slightly smaller).
   - Thermal LEFT, Document RIGHT.
   - Flying-in label PDF (top-left) and packing slip (top-right)
     fly to the laptop. NO connector lines from the IN labels.
   - Bigger LABEL JOB IN / DOCUMENT JOB IN labels.
   - V2 printer art with the printer's own output animated
     IN-PLACE (no tiny strips floating away).
------------------------------------------------------------ */
const A6_DesktopUtility = ({ motion = true, annotated = true, showLabels = true, staticPose = false }) => {
  const W = 1000, H = 600;
  const animate = motion && !staticPose;

  // Desk top at scene y=500. Printers rest ON the desk:
  //   thermal printer (160 tall) → translate.y = 340
  //   doc printer (184 tall)     → translate.y = 316
  // Step 5.3 / 5.4 text sits BELOW the desk (scene y > 560) so it doesn't
  // collide with the desk graphic — readable in the 40px strip y=560..600.
  // Documents travel along straight dotted lines from labels to laptop center
  // Label job in: from upper-left (x=40,y=130) → laptop center (x=500,y=390)
  // Doc job in: from upper-right (x=960,y=130) → laptop center (x=500,y=390)
  const labelPath = "M 80 130 L 500 390";
  const docPath   = "M 920 130 L 500 390";

  return (
    <div style={{ width: "100%", aspectRatio: `${W} / ${H}` }}>
      <svg viewBox={`0 0 ${W} ${H}`} width="100%" height="100%" style={{ display: "block", overflow: "visible" }}>
        <defs>
          <linearGradient id="a7-4-bg" x1="0" x2="0" y1="0" y2="1">
            <stop offset="0" stopColor={PALETTE.paper}/><stop offset="1" stopColor={PALETTE.paper2}/>
          </linearGradient>
          <linearGradient id="a7-4-desk" x1="0" x2="0" y1="0" y2="1">
            <stop offset="0" stopColor={PALETTE.paper3}/><stop offset="1" stopColor={PALETTE.paper4}/>
          </linearGradient>
          {/* Thermal printer slot clip — only show label content at y >= 98 (slot bottom in
              printer-local coords). Hides anything above the slot, so the label appears to
              emerge from the slot rather than materialize on top of the printer body. */}
          <clipPath id="a7-4-slot-clip">
            <rect x="0" y="98" width="200" height="200"/>
          </clipPath>
          {/* Doc printer letter clip — only show paper at y < 70 (printer top edge in printer-local
              coords). Hides anything below the top edge, so the letter appears to emerge from the
              top tray rather than be visible inside the printer body. */}
          <clipPath id="a7-4-letter-clip">
            <rect x="-100" y="-300" width="500" height="370"/>
          </clipPath>
        </defs>
        <rect width={W} height={H} fill="url(#a7-4-bg)"/>


        {showLabels && (
          <Tag x={40} y={36} text="05 · DESKTOP UTILITY" color={PALETTE.honeyDk} size={14} weight={600}/>
        )}

        {/* Step labels — same Geist Mono style as other steps */}
        <text x="40" y="90" fontFamily="Geist Mono, monospace" fontSize="11" fill={PALETTE.honeyDk} fontWeight="700" letterSpacing="0.14em">5.1 · LABEL PRINT JOB</text>
        <text x="40" y="106" fontFamily="Geist, sans-serif" fontSize="11" fill={PALETTE.ink4}>from the browser extension</text>
        <text x="960" y="90" fontFamily="Geist Mono, monospace" fontSize="11" fill={PALETTE.honeyDk} textAnchor="end" fontWeight="700" letterSpacing="0.14em">5.2 · DOCUMENT PRINT JOB</text>
        <text x="960" y="106" fontFamily="Geist, sans-serif" fontSize="11" fill={PALETTE.ink4} textAnchor="end">from the Shopify app</text>

        {/* Dotted guide lines from step labels → laptop — drawn BEFORE documents so docs render on top */}
        <path d={labelPath} fill="none" stroke={PALETTE.honeyLn} strokeWidth="1.4" strokeDasharray="5 4" opacity="0.55">
          {animate && <animate attributeName="stroke-dashoffset" from="0" to="-36" dur="1.8s" repeatCount="indefinite"/>}
        </path>
        <path d={docPath} fill="none" stroke={PALETTE.honeyLn} strokeWidth="1.4" strokeDasharray="5 4" opacity="0.55">
          {animate && <animate attributeName="stroke-dashoffset" from="0" to="-36" dur="1.8s" repeatCount="indefinite" begin="0.3s"/>}
        </path>

        {/* FLYING SHIPPING LABEL — follows the label path exactly.
            Static pose: freeze ~15% along the path (110, 150). Reads as
            "just launched from the upper-left corner" — well separated
            from the laptop, doc clearly in the upper portion of its arc. */}
        <g transform={staticPose ? "translate(110, 150)" : "translate(80, 130)"}>
          {animate && (
            <animateTransform attributeName="transform" type="translate"
                              values="80 130; 80 130; 200 210; 340 300; 460 375; 500 390; 500 390"
                              keyTimes="0; 0.1; 0.3; 0.5; 0.62; 0.70; 1" dur="5s" repeatCount="indefinite"/>
          )}
          <g opacity={staticPose ? "1" : undefined}>
            {animate && <animate attributeName="opacity" values="0;1;1;1;1;0" keyTimes="0;0.1;0.3;0.62;0.70;0.74" dur="5s" repeatCount="indefinite"/>}
            <rect x="2" y="3" width="84" height="100" rx="3" fill={PALETTE.ink} opacity="0.12"/>
            <rect x="0" y="0" width="84" height="100" rx="3" fill="#FAFAF7" stroke={PALETTE.ink} strokeWidth="1.2"/>
            <text x="6" y="12" fontFamily="Geist Mono, monospace" fontSize="6" fill={PALETTE.ink3} letterSpacing="0.1em">USPS PRIORITY MAIL</text>
            <text x="6" y="20" fontFamily="Geist Mono, monospace" fontSize="5" fill={PALETTE.ink5}>FROM: Brooklyn, NY</text>
            <text x="6" y="27" fontFamily="Geist Mono, monospace" fontSize="5" fill={PALETTE.ink5}>TO: Austin, TX</text>
            <g transform="translate(6, 34)">
              {[0,2,5,7,10,12,15,17,19,22,25,28,30,33,36,38,41,44,47,50,53,56,59,62,65,68,71].map((x, i) => (
                <rect key={i} x={x} y="0" width={i % 3 === 0 ? 1.6 : 0.8} height="22" fill={PALETTE.ink}/>
              ))}
            </g>
            <text x="42" y="68" fontFamily="Geist Mono, monospace" fontSize="4.5" fill={PALETTE.ink3} textAnchor="middle">9405 5036 9930 0042 1234</text>
            <rect x="6" y="74" width="48" height="2" fill={PALETTE.ink}/>
            <rect x="6" y="79" width="56" height="1.5" fill={PALETTE.ink5}/>
            <rect x="6" y="84" width="44" height="1.5" fill={PALETTE.ink5}/>
            <rect x="6" y="89" width="40" height="1.5" fill={PALETTE.ink5}/>
            <rect x="64" y="76" width="14" height="14" fill={PALETTE.ink}/>
            <rect x="66" y="78" width="2" height="2" fill={PALETTE.paper}/>
            <rect x="74" y="78" width="2" height="2" fill={PALETTE.paper}/>
            <rect x="66" y="86" width="2" height="2" fill={PALETTE.paper}/>
            <rect x="70" y="82" width="2" height="2" fill={PALETTE.paper}/>
            <Face cx={68} cy={6} r={4}/>
          </g>
        </g>

        {/* FLYING PACKING SLIP — top-RIGHT corner tracks docPath (mirror of label's top-LEFT
            on labelPath), so the dotted line passes through the slip's body diagonally
            instead of running alongside it. Each x is the docPath x minus the slip width (76). */}
        <g transform={staticPose ? "translate(814, 150)" : "translate(844, 130)"}>
          {animate && (
            <animateTransform attributeName="transform" type="translate"
                              values="844 130; 844 130; 724 210; 584 300; 464 375; 424 390; 424 390"
                              keyTimes="0; 0.1; 0.3; 0.5; 0.62; 0.70; 1" dur="5s" repeatCount="indefinite" begin="0.3s"/>
          )}
          <g opacity={staticPose ? "1" : undefined}>
            {animate && <animate attributeName="opacity" values="0;1;1;1;1;0" keyTimes="0;0.1;0.3;0.62;0.70;0.74" dur="5s" repeatCount="indefinite" begin="0.3s"/>}
            <rect x="2" y="3" width="76" height="100" rx="2" fill={PALETTE.ink} opacity="0.12"/>
            <rect x="0" y="0" width="76" height="100" rx="2" fill="#FAFAF7" stroke={PALETTE.ink} strokeWidth="1.2"/>
            <text x="6" y="12" fontFamily="Geist, sans-serif" fontSize="7" fill={PALETTE.ink} fontWeight="700">PACKING SLIP</text>
            <text x="6" y="19" fontFamily="Geist Mono, monospace" fontSize="4.5" fill={PALETTE.ink5}>ORDER #1042 · 2 ITEMS</text>
            <line x1="6" y1="22" x2="70" y2="22" stroke={PALETTE.ink5} strokeWidth="0.5"/>
            <rect x="6" y="26" width="32" height="1.5" fill={PALETTE.ink}/>
            <rect x="6" y="30" width="44" height="1.2" fill={PALETTE.ink5}/>
            <rect x="6" y="34" width="36" height="1.2" fill={PALETTE.ink5}/>
            <line x1="6" y1="42" x2="70" y2="42" stroke={PALETTE.ink5} strokeWidth="0.5"/>
            <text x="6" y="48" fontFamily="Geist Mono, monospace" fontSize="4" fill={PALETTE.ink4}>ITEM</text>
            <text x="56" y="48" fontFamily="Geist Mono, monospace" fontSize="4" fill={PALETTE.ink4}>QTY</text>
            <line x1="6" y1="51" x2="70" y2="51" stroke={PALETTE.ink5} strokeWidth="0.5"/>
            <rect x="6" y="55" width="40" height="1.2" fill={PALETTE.ink5}/>
            <text x="62" y="57" fontFamily="Geist Mono, monospace" fontSize="4" fill={PALETTE.ink3}>1</text>
            <rect x="6" y="62" width="36" height="1.2" fill={PALETTE.ink5}/>
            <text x="62" y="64" fontFamily="Geist Mono, monospace" fontSize="4" fill={PALETTE.ink3}>1</text>
            <line x1="6" y1="70" x2="70" y2="70" stroke={PALETTE.ink5} strokeWidth="0.5"/>
            <g transform="translate(6, 78)">
              {[0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58].map((x, i) => (
                <rect key={i} x={x} y="0" width={i % 2 === 0 ? 0.8 : 1.2} height="12" fill={PALETTE.ink}/>
              ))}
            </g>
            <text x="38" y="96" fontFamily="Geist Mono, monospace" fontSize="4" fill={PALETTE.ink3} textAnchor="middle">SO-1042</text>
          </g>
        </g>

        {/* desk surface — top edge at scene y=473 so laptop + printers (bases at y=500)
            visually sit ON the desk surface rather than at its back edge */}
        <g transform="translate(0, 473)">
          <path d="M 60 0 L 940 0 L 1000 60 L 0 60 Z" fill="url(#a7-4-desk)"/>
          <path d="M 60 0 L 940 0 L 1000 60 L 0 60 Z" fill="none" stroke={PALETTE.ink} strokeWidth="1.2" strokeLinejoin="round"/>
        </g>

        {/* DESKTOP UTILITY — laptop center, sitting on desk at y=500 */}
        <g transform="translate(390, 350)">
          {/* laptop base sits at y=150 which = y=500 globally */}
          <path d="M -14 150 L 232 150 L 244 166 L -26 166 Z" fill={PALETTE.paper4} stroke={PALETTE.ink} strokeWidth="1.2"/>
          <rect x="0" y="0" width="218" height="148" rx="8" fill={PALETTE.ink}/>
          <rect x="6" y="6" width="206" height="136" rx="4" fill={PALETTE.paper2}/>
          <rect x="6" y="6" width="206" height="20" rx="4" fill={PALETTE.ink}/>
          {/* Autoprinter favicon — inline mirror of marketing-site/assets/favicon.svg, sized 16×16
              at scene-level (16/64 = 0.25 scale of the 64×64 source artwork). Replaces the previous
              APMarkV5 call which rendered the A in PALETTE.ink against an ink background — invisible.
              This version uses explicit cream A + ink cutouts so the mark reads on the dark header. */}
          <g transform="translate(10, 8) scale(0.25)">
            <rect x="0" y="0" width="64" height="64" rx="12" fill={PALETTE.ink}/>
            <path d="M22.4 8 L41.6 8 L57 50 L46.5 50 L42.8 39.5 L21.2 39.5 L17.5 50 L7 50 Z" fill={PALETTE.paper}/>
            <path d="M30 8 L41.6 8 L36 22 Z" fill={PALETTE.ink}/>
            <path d="M32 16.4 L38.6 31.5 L25.4 31.5 Z" fill={PALETTE.ink}/>
            <rect x="7" y="54" width="50" height="3" fill={PALETTE.honey}/>
          </g>
          <text x="32" y="20" fontFamily="Geist Mono, monospace" fontSize="8" fill={PALETTE.paper} letterSpacing="0.16em" fontWeight="700">AUTOPRINTER · UTILITY</text>
          <circle cx="200" cy="16" r="3" fill={PALETTE.ok}>
            {animate && <animate attributeName="opacity" values="1;0.4;1" dur="1.6s" repeatCount="indefinite"/>}
          </circle>
          <text x="14" y="42" fontFamily="Geist Mono, monospace" fontSize="7" fill={PALETTE.ink3} letterSpacing="0.1em" fontWeight="600">DISPATCH</text>
          {[
            ["#1042 · label", "→ THERMAL", PALETTE.ok],
            ["#1042 · slip", "→ DOCUMENT", PALETTE.ok],
            ["#1043 · label", "→ THERMAL", PALETTE.ok],
            ["#1044 · invoice", "→ DOCUMENT", PALETTE.honeyDk],
          ].map(([l, r, c], i) => (
            <g key={i} transform={`translate(14, ${50 + i * 18})`}>
              <rect x="0" y="0" width="190" height="14" rx="2" fill={PALETTE.paper}/>
              <circle cx="6" cy="7" r="2" fill={c}/>
              <text x="14" y="10" fontFamily="Geist Mono, monospace" fontSize="6.5" fill={PALETTE.ink3}>{l}</text>
              <text x="184" y="10" fontFamily="Geist Mono, monospace" fontSize="6.5" fill={PALETTE.honeyDk} textAnchor="end" fontWeight="700">{r}</text>
            </g>
          ))}
        </g>

        {/* Printer ID labels — rendered BEFORE the printer groups so the printers' emerging
            paper renders ON TOP of these labels (specifically the DOCUMENT label gets covered
            by the rising packing slip, which is intended). Labels don't overlap with printer
            bodies geometrically, so rendering before the printers doesn't hide them. */}
        <g>
          <Tag x={170} y={388} text="THERMAL · 4×6"     anchor="middle" color={PALETTE.ink4} size={10}/>
          <Tag x={830} y={370} text="DOCUMENT · LETTER" anchor="middle" color={PALETTE.ink4} size={10}/>
        </g>

        {/* THERMAL PRINTER (LEFT) — scale 0.8 (down-sized to read better next to laptop + doc printer);
            body bottom anchored at scene y=500, horizontal center anchored at scene x=170. Shadow
            is inside this group so it shrinks proportionally and stays just under the new feet. */}
        <g transform="translate(90, 372) scale(0.8)">
          <ellipse cx="100" cy="171" rx="92" ry="7" fill={PALETTE.ink} opacity="0.10"/>
          <path d="M 16 60 L 184 60 L 196 76 L 196 160 L 4 160 L 4 76 Z" fill={PALETTE.ink} stroke={PALETTE.ink} strokeWidth="1.2"/>
          <path d="M 4 76 Q 100 30 196 76" fill={PALETTE.ink2} stroke={PALETTE.ink} strokeWidth="1.2"/>
          <rect x="20" y="92" width="160" height="6" fill={PALETTE.paper}/>
          <circle cx="170" cy="118" r="4" fill={PALETTE.honey}>
            {animate && <animate attributeName="opacity" values="1;0.5;1" dur="1.4s" repeatCount="indefinite"/>}
          </circle>
          <rect x="20" y="114" width="20" height="10" rx="2" fill={PALETTE.paper3}/>
          {/* Printer feet — drawn BEFORE the label group below so the emerging label renders ON TOP
              of them rather than being covered. */}
          <rect x="14" y="158" width="12" height="6" fill={PALETTE.ink3}/>
          <rect x="174" y="158" width="12" height="6" fill={PALETTE.ink3}/>
          {/* LABEL OUTPUT — emerges DOWNWARD from the front slot (Option C).
              - Outer wrapper applies the slot clip path so anything above local y=98 is hidden
                (looks like paper feeding out of the slot rather than materializing on top).
              - Middle wrapper carries the translate animation (slides label down through slot).
              - Inner wrapper rotates the label 180° around its center (78, 52) so the leading
                edge of the printed content emerges first — text reads upside-down on screen,
                which is the realistic orientation for paper exiting head-first. Garrett picked
                this over the simpler "no flip" version (Option A).
              - No opacity animations needed — the clip path handles visibility. */}
          <g clipPath="url(#a7-4-slot-clip)">
            <g transform={staticPose ? "translate(22, 98)" : "translate(22, -6)"}>
              {animate && (
                <animateTransform attributeName="transform" type="translate"
                                  values="22 -6; 22 -6; 22 50; 22 98; 22 98; 22 98"
                                  keyTimes="0; 0.55; 0.7; 0.85; 0.92; 1" dur="5s" repeatCount="indefinite"/>
              )}
              {/* Pause-then-fade exit: label holds at y=98 (fully emerged) from t=0.85 to 0.92,
                  then opacity fades 1→0 from 0.92 to 1.0. Replaces the previous "slide off bottom"
                  exit (which always-cleared via clip but felt abrupt).
                  Static pose holds at fully-emerged opacity=1. */}
              {animate && (
                <animate attributeName="opacity"
                         values="1; 1; 1; 1; 1; 0"
                         keyTimes="0; 0.55; 0.7; 0.85; 0.92; 1" dur="5s" repeatCount="indefinite"/>
              )}
              <g transform="rotate(180 78 52)">
                <rect x="-2" y="2" width="156" height="104" rx="3" fill={PALETTE.ink} opacity="0.12"/>
                <rect x="0" y="0" width="156" height="104" rx="3" fill="#FAFAF7" stroke={PALETTE.ink} strokeWidth="1"/>
                <text x="8" y="12" fontFamily="Geist Mono, monospace" fontSize="6" fill={PALETTE.ink3} letterSpacing="0.1em">USPS PRIORITY</text>
                <text x="8" y="20" fontFamily="Geist Mono, monospace" fontSize="5" fill={PALETTE.ink5}>BROOKLYN, NY → AUSTIN, TX</text>
                <g transform="translate(8, 30)">
                  {[0,2,5,7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58,61,64,67,70,73,76,79,82,85,88,91,94,97,100,103,106,109,112,115,118,121,124,127,130,133,136].map((x, i) => (
                    <rect key={i} x={x} y="0" width={i % 3 === 0 ? 1.6 : 0.8} height="36" fill={PALETTE.ink}/>
                  ))}
                </g>
                <text x="78" y="78" fontFamily="Geist Mono, monospace" fontSize="5" fill={PALETTE.ink3} textAnchor="middle">9405 5036 9930 0042 1234</text>
                <rect x="8" y="84" width="60" height="2" fill={PALETTE.ink}/>
                <rect x="8" y="90" width="80" height="1.5" fill={PALETTE.ink5}/>
                <rect x="8" y="96" width="56" height="1.5" fill={PALETTE.ink5}/>
                <rect x="120" y="82" width="22" height="16" fill={PALETTE.ink}/>
              </g>
            </g>
          </g>
          {/* 5.3 step text + THERMAL · 4×6 printer label — moved OUT of this scaled (0.8) group
              so they render at scene-level scale and align with 5.1/5.2. See the top-level
              "step labels for printers" group below the doc printer. */}
        </g>

        {/* DOCUMENT PRINTER (RIGHT) — sits on desk: body bottom (local y=184) lands at scene y=500 */}
        <g transform="translate(710, 316)">
          <ellipse cx="120" cy="196" rx="110" ry="8" fill={PALETTE.ink} opacity="0.10"/>
          <path d="M 20 70 L 220 70 L 232 86 L 232 184 L 8 184 L 8 86 Z" fill={PALETTE.paper2} stroke={PALETTE.ink} strokeWidth="1.4" strokeLinejoin="round"/>
          <path d="M 30 70 L 210 70 L 218 84 L 22 84 Z" fill={PALETTE.paper3} stroke={PALETTE.ink} strokeWidth="1.2" strokeLinejoin="round"/>
          {/* LETTER OUTPUT — emerges UPWARD from the top tray.
              - Outer wrapper: letter clip path hides anything at y >= 70 (the printer top edge),
                so the paper appears to feed out of the top tray rather than be visible inside.
              - Middle wrapper: translate animation (paper top from y=70 to y=-63 = ~2/3 emerged).
              - Opacity animation: pause briefly then fade away (matches thermal label exit pattern).
              - Inner wrapper: scale(2) so the flying-packing-slip content (76×100 design at the
                upper-right of the canvas) renders here at letter-paper proportions (152×200,
                ratio 0.76 ≈ 8.5×11). Garrett asked to reuse the flying slip's content. */}
          <g clipPath="url(#a7-4-letter-clip)">
            <g transform={staticPose ? "translate(44, -63)" : "translate(44, 70)"}>
              {animate && (
                <animateTransform attributeName="transform" type="translate"
                                  values="44 70; 44 70; 44 -63; 44 -63; 44 -63"
                                  keyTimes="0; 0.55; 0.85; 0.92; 1" dur="5s" repeatCount="indefinite" begin="0.3s"/>
              )}
              {animate && (
                <animate attributeName="opacity"
                         values="1; 1; 1; 1; 0"
                         keyTimes="0; 0.55; 0.85; 0.92; 1" dur="5s" repeatCount="indefinite" begin="0.3s"/>
              )}
              <g transform="scale(2)">
                <rect x="2" y="3" width="76" height="100" rx="2" fill={PALETTE.ink} opacity="0.12"/>
                <rect x="0" y="0" width="76" height="100" rx="2" fill="#FAFAF7" stroke={PALETTE.ink} strokeWidth="1.2"/>
                <text x="6" y="12" fontFamily="Geist, sans-serif" fontSize="7" fill={PALETTE.ink} fontWeight="700">PACKING SLIP</text>
                <text x="6" y="19" fontFamily="Geist Mono, monospace" fontSize="4.5" fill={PALETTE.ink5}>ORDER #1042 · 2 ITEMS</text>
                <line x1="6" y1="22" x2="70" y2="22" stroke={PALETTE.ink5} strokeWidth="0.5"/>
                <rect x="6" y="26" width="32" height="1.5" fill={PALETTE.ink}/>
                <rect x="6" y="30" width="44" height="1.2" fill={PALETTE.ink5}/>
                <rect x="6" y="34" width="36" height="1.2" fill={PALETTE.ink5}/>
                <line x1="6" y1="42" x2="70" y2="42" stroke={PALETTE.ink5} strokeWidth="0.5"/>
                <text x="6" y="48" fontFamily="Geist Mono, monospace" fontSize="4" fill={PALETTE.ink4}>ITEM</text>
                <text x="56" y="48" fontFamily="Geist Mono, monospace" fontSize="4" fill={PALETTE.ink4}>QTY</text>
                <line x1="6" y1="51" x2="70" y2="51" stroke={PALETTE.ink5} strokeWidth="0.5"/>
                <rect x="6" y="55" width="40" height="1.2" fill={PALETTE.ink5}/>
                <text x="62" y="57" fontFamily="Geist Mono, monospace" fontSize="4" fill={PALETTE.ink3}>1</text>
                <rect x="6" y="62" width="36" height="1.2" fill={PALETTE.ink5}/>
                <text x="62" y="64" fontFamily="Geist Mono, monospace" fontSize="4" fill={PALETTE.ink3}>1</text>
                <line x1="6" y1="70" x2="70" y2="70" stroke={PALETTE.ink5} strokeWidth="0.5"/>
                <g transform="translate(6, 78)">
                  {[0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58].map((x, i) => (
                    <rect key={i} x={x} y="0" width={i % 2 === 0 ? 0.8 : 1.2} height="12" fill={PALETTE.ink}/>
                  ))}
                </g>
                <text x="38" y="96" fontFamily="Geist Mono, monospace" fontSize="4" fill={PALETTE.ink3} textAnchor="middle">SO-1042</text>
              </g>
            </g>
          </g>
          <rect x="22" y="138" width="200" height="44" rx="3" fill={PALETTE.paper3}/>
          <circle cx="40" cy="160" r="4" fill={PALETTE.ok}>
            {animate && <animate attributeName="opacity" values="1;0.4;1" dur="1.6s" repeatCount="indefinite"/>}
          </circle>
          <rect x="56" y="152" width="100" height="3" fill={PALETTE.ink4}/>
          <rect x="56" y="160" width="80" height="3" fill={PALETTE.ink5}/>
          <rect x="56" y="168" width="60" height="3" fill={PALETTE.ink5}/>
          <rect x="172" y="148" width="40" height="22" rx="2" fill={PALETTE.paper2} stroke={PALETTE.rule}/>
          <rect x="20" y="182" width="14" height="6" fill={PALETTE.ink3}/>
          <rect x="206" y="182" width="14" height="6" fill={PALETTE.ink3}/>
          {/* 5.4 step text + DOCUMENT · LETTER printer label — moved OUT of this group so they
              render at scene-level scale and align with 5.2 right-anchor. See the top-level
              "step labels for printers" group below. */}
        </g>

        {/* Step text 5.3 / 5.4 — moved UP slightly (568→560 title, 584→576 subtitle) so the strip
            below the desk reads tighter, while still leaving comfortable space above the desk
            bottom edge (y=533) and above the canvas bottom (y=600). 5.3 left-anchored, 5.4
            right-anchored, matching 5.1/5.2's styling exactly. */}
        <g>
          <text x="40" y="560" fontFamily="Geist Mono, monospace" fontSize="11" fill={PALETTE.honeyDk} fontWeight="700" letterSpacing="0.14em">5.3 · LABEL → THERMAL</text>
          <text x="40" y="576" fontFamily="Geist, sans-serif" fontSize="11" fill={PALETTE.ink4}>Shipping label routes to the 4×6 thermal.</text>

          <text x="960" y="560" fontFamily="Geist Mono, monospace" fontSize="11" fill={PALETTE.honeyDk} textAnchor="end" fontWeight="700" letterSpacing="0.14em">5.4 · DOC → DOCUMENT</text>
          <text x="960" y="576" fontFamily="Geist, sans-serif" fontSize="11" fill={PALETTE.ink4} textAnchor="end">Slip and invoice route to the document printer.</text>
        </g>

        {/* CABLES — utility ↔ printers */}
        <g>
          <path d="M 390 500 C 350 516 310 516 251 498" fill="none" stroke={PALETTE.ink3} strokeWidth="1.6" strokeLinecap="round"/>
          {animate && (
            <circle r="3.5" fill={PALETTE.honey}>
              <animateMotion dur="5s" repeatCount="indefinite"
                             keyTimes="0;0.18;0.3;0.4;1" keyPoints="0;0;0.5;1;1"
                             path="M 390 500 C 350 516 310 516 251 498"/>
              <animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.18;0.22;0.36;0.4;1" dur="5s" repeatCount="indefinite"/>
            </circle>
          )}
          <path d="M 614 500 C 654 520 690 520 730 502" fill="none" stroke={PALETTE.ink3} strokeWidth="1.6" strokeLinecap="round"/>
          {animate && (
            <circle r="3.5" fill={PALETTE.honey}>
              <animateMotion dur="5s" repeatCount="indefinite"
                             keyTimes="0;0.32;0.46;0.56;1" keyPoints="0;0;0.5;1;1"
                             path="M 614 500 C 654 520 690 520 730 502"/>
              <animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.32;0.36;0.52;0.56;1" dur="5s" repeatCount="indefinite"/>
            </circle>
          )}
        </g>

      </svg>
    </div>
  );
};

Object.assign(window, {
  A7_AutoprinterRouting: A6_AutoprinterRouting,
  A7_DesktopUtility: A6_DesktopUtility,
});
