/* global React */
// Sendvo · Interactive landing page.
// Hero is a working postcard preview + an ROI calculator that recomputes
// price as you drag a volume slider. Pipeline animates "out the door."
// Sections: hero, numbers strip, pipeline timeline, comparison table,
// use cases, integrations, quote, CTA, footer.

const { useState, useEffect, useRef } = React;

const V2Nav = () => (
  <nav style={{
    background: 'var(--sv-bg-elevated)', borderBottom: '1px solid var(--sv-ash)',
    position: 'sticky', top: 0, zIndex: 5,
  }}>
    <div className="sv-nav-row" style={{ padding: '14px 56px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 36 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <window.SVMark size={22}/>
          <window.SVWordmark size={22}/>
        </div>
        <div className="sv-mobile-hide" style={{ display: 'flex', alignItems: 'center', gap: 26 }}>
          {[
            { label: 'Product',      href: '/product' },
            { label: 'Templates',    href: '/templates' },
            { label: 'Pricing',      href: '/pricing' },
            { label: 'Integrations', href: '/integrations' },
            { label: 'Customers',    href: '/customers' },
            { label: 'Pitch Deck',   href: 'assets/sendvo-seed-pitch.pdf', target: '_blank' },
          ].map(l => (
            <a
              key={l.label}
              href={l.href}
              className="sv-link"
              {...(l.target ? { target: l.target, rel: 'noopener' } : {})}
              style={{ fontFamily: 'var(--sv-font-body)', fontWeight: 500, fontSize: 'var(--sv-text-link)' }}
            >{l.label}</a>
          ))}
        </div>
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
        <window.SVPill color="var(--sv-volt)" bg="color-mix(in srgb, var(--sv-volt) 8%, transparent)" style={{ color: 'var(--sv-volt)' }}>NOW IN BETA</window.SVPill>
        <a href="https://app.sendvo.io/login" className="sv-link sv-mobile-hide" style={{ fontFamily: 'var(--sv-font-body)', fontWeight: 500, fontSize: 'var(--sv-text-link)' }}>Log in</a>
        <window.SVBtn variant="dark" size="md" href="https://app.sendvo.io/signup">Start sending</window.SVBtn>
      </div>
    </div>
  </nav>
);

// Hero demo — the right-side panel.
// Three tabs walking the user through the product in order: build the audience,
// design the postcard, watch the delivery dashboard light up.
const HeroDemo = () => {
  const t = window.useT();
  const winW = window.useWindowWidth();
  const [tab, setTab] = useState('audience');
  const [variant, setVariant] = useState(t.heroCard || 'cash-offer');
  React.useEffect(() => { setVariant(t.heroCard); }, [t.heroCard]);
  const [side, setSide] = useState('front');
  const [geo, setGeo] = useState('zip');
  const [delivered, setDelivered] = useState(1847);

  // Tracking dashboard "ticks" a few deliveries every couple seconds.
  React.useEffect(() => {
    if (tab !== 'tracking') return;
    const id = setInterval(() => {
      setDelivered(d => d < 2040 ? d + Math.floor(Math.random() * 3 + 1) : d);
    }, 1400);
    return () => clearInterval(id);
  }, [tab]);

  // ── AUDIENCE MAP DATA ───────────────────────────────────────────────────
  // Real Manhattan ZIP geometries come from `window.NYC_MANHATTAN_ZIPS`
  // (loaded from nyc-svg.jsx, projected from NYC OpenData MODZCTA GeoJSON
  // into a 536×360 viewBox using equirectangular + Mercator-lat-stretch).
  // We keep our 16 "labeled" ZIPs here with their place + count metadata;
  // the actual polygon path `d` is looked up at render time so we always
  // use the real geometry. Codes correspond to the user's reference map.
  const ZIP_LABELS = [
    { code: '10026', place: '10026 · harlem, ny',          count: '2,340' },
    { code: '10025', place: '10025 · morningside heights', count: '4,210' },
    { code: '10024', place: '10024 · upper west side',     count: '2,860' },
    { code: '10023', place: '10023 · lincoln square',      count: '1,920' },
    { code: '10069', place: '10069 · riverside south',     count: '610' },
    { code: '10065', place: '10065 · upper east side',     count: '2,440' },
    { code: '10019', place: "10019 · hell's kitchen",      count: '3,420' },
    { code: '10036', place: '10036 · times square',        count: '1,790' },
    { code: '10016', place: '10016 · murray hill',         count: '2,820' },
    { code: '10001', place: '10001 · chelsea, ny',         count: '3,180' },
    { code: '10010', place: '10010 · gramercy / flatiron', count: '1,420' },
    { code: '10003', place: '10003 · east village',        count: '3,090' },
    { code: '10014', place: '10014 · west village',        count: '2,140' },
    { code: '10002', place: '10002 · lower east side',     count: '4,820' },
    { code: '10038', place: '10038 · financial district',  count: '1,120' },
    { code: '10282', place: '10282 · battery park city',   count: '820' },
  ];
  // Unified all-ZIPs map (Manhattan + surrounding boroughs). Every entry
  // becomes clickable in zip mode. Each ZIP has {code, borough, pop, d}.
  const ALL_ZIPS_LIST = [
    ...((typeof window !== 'undefined' && window.NYC_MANHATTAN_ZIPS) || []),
    ...((typeof window !== 'undefined' && window.NYC_CONTEXT_ZIPS) || []),
  ];
  const ALL_ZIPS = Object.fromEntries(ALL_ZIPS_LIST.map(z => [z.code, z]));
  const ZIP_LABELS_MAP = Object.fromEntries(ZIP_LABELS.map(l => [l.code, l]));
  const BOROUGH_NAMES = {
    manhattan: 'manhattan', brooklyn: 'brooklyn', queens: 'queens',
    bronx: 'bronx', staten_island: 'staten island',
  };

  // Resolve the ZIP currently selected by `zipCode`. Labeled ZIPs get their
  // hand-curated place + count; unlabeled ones synthesize a place from the
  // borough and a count from the GeoJSON `pop_est` divided by 7 (rough
  // households-per-pop ratio — keeps demo counts in the same magnitude as the
  // labeled ones).
  const resolveZip = (code) => {
    const z = ALL_ZIPS[code];
    if (!z) return null;
    const label = ZIP_LABELS_MAP[code];
    if (label) return { ...z, place: label.place, count: label.count };
    const boroughName = BOROUGH_NAMES[z.borough] || z.borough;
    const popNum = z.pop ? parseInt(z.pop, 10) : 0;
    const count = popNum ? Math.round(popNum / 7).toLocaleString() : '—';
    return { ...z, place: `${z.code} · ${boroughName}, ny`, count };
  };

  // County mode — NY-metro counties as a chip-grid picker (replaces the
  // prior SVG polygon over the NYC map, which didn't read as Manhattan and
  // wasn't interactive). State mode (below) similarly uses a real US map
  // SVG from `window.US_STATES`.
  // County counts are demo-only "addresses available" figures, roughly 1/4
  // of real US Census household totals — high enough to feel substantial but
  // not so high that they dwarf the ZIP-level numbers.
  const COUNTIES = [
    { code: 'NY', name: 'New York',    sub: 'manhattan',     count: '165,400' },
    { code: 'KI', name: 'Kings',       sub: 'brooklyn',      count: '215,700' },
    { code: 'QU', name: 'Queens',      sub: 'queens',        count: '198,300' },
    { code: 'BX', name: 'Bronx',       sub: 'bronx',         count: '124,800' },
    { code: 'RI', name: 'Richmond',    sub: 'staten island', count: '38,200'  },
    { code: 'NA', name: 'Nassau',      sub: 'nassau',        count: '156,400' },
    { code: 'SU', name: 'Suffolk',     sub: 'suffolk',       count: '184,200' },
    { code: 'WE', name: 'Westchester', sub: 'westchester',   count: '92,500'  },
  ];

  const MAP_CENTER = [268, 180];
  const centroid = (pts) => {
    if (!pts.length) return MAP_CENTER;
    const n = pts.length;
    return [pts.reduce((s,[x])=>s+x,0)/n, pts.reduce((s,[,y])=>s+y,0)/n];
  };
  // Parse simple M/L SVG path → array of [x,y] points (no curves).
  const pathToPoints = (d) =>
    d.replace(/[MZL]/g, ' ').trim().split(/\s+/).filter(Boolean)
     .map(p => p.split(',').map(Number));

  // Draw mode — points are draggable handles on a fixed-size polygon. Reset
  // restores the default shape rather than emptying the polygon.
  // 6-point hexagon over mid-Manhattan (Chelsea / Midtown vicinity) in the
  // new projection — viewBox 0 0 536 360 with Manhattan occupying roughly
  // x=145-290, y=20-340.
  const DEFAULT_DRAW = [[200,165], [250,155], [265,195], [255,230], [210,240], [185,205]];
  const [drawPoints, setDrawPoints] = useState(DEFAULT_DRAW);
  const [draggingIdx, setDraggingIdx] = useState(null);
  const [zipCode, setZipCode] = useState('10001'); // default to Chelsea
  const [countyIdx, setCountyIdx] = useState(0); // default to New York / Manhattan
  // Default state mode to NY in window.US_STATES (loaded from us-states.jsx).
  const [stateIdx, setStateIdx] = useState(() => {
    const list = (typeof window !== 'undefined' && window.US_STATES) || [];
    const i = list.findIndex(s => s.code === 'NY');
    return i >= 0 ? i : 0;
  });
  // Ref to the currently-selected state's path so we can place a name label
  // over its geographic center via getBBox after render.
  const selectedStateRef = useRef(null);
  const [stateLabelPos, setStateLabelPos] = useState(null);
  useEffect(() => {
    if (geo !== 'state' || !selectedStateRef.current) {
      setStateLabelPos(null);
      return;
    }
    const bbox = selectedStateRef.current.getBBox();
    setStateLabelPos({ cx: bbox.x + bbox.width / 2, cy: bbox.y + bbox.height / 2 });
  }, [geo, stateIdx]);

  // Pointer→SVG-viewBox math. Mouse events expose clientX/Y directly;
  // touch events nest the point in `touches[0]` (or `changedTouches[0]`
  // once the finger has lifted). Normalize before projecting.
  const svgPointFromEvent = (e) => {
    const r = e.currentTarget.getBoundingClientRect();
    const pt = e.touches && e.touches[0] ? e.touches[0]
            : (e.changedTouches && e.changedTouches[0] ? e.changedTouches[0] : e);
    return [
      Math.round(((pt.clientX - r.left) / r.width) * 536),
      Math.round(((pt.clientY - r.top) / r.height) * 360),
    ];
  };
  const handleSVGMouseMove = (e) => {
    if (draggingIdx === null) return;
    const [x, y] = svgPointFromEvent(e);
    setDrawPoints(prev => prev.map((p, i) => i === draggingIdx ? [x, y] : p));
  };
  const handleSVGMouseUp = () => setDraggingIdx(null);
  // Touch equivalent of mouse-move. preventDefault on the SVG so the
  // browser doesn't claim the gesture for vertical scroll (touchAction
  // 'none' on the <svg> covers it pre-emptively; the explicit guard
  // here is for older browsers that ignore touch-action).
  const handleSVGTouchMove = (e) => {
    if (draggingIdx === null) return;
    if (e.cancelable) e.preventDefault();
    handleSVGMouseMove(e);
  };
  const handleSVGTouchEnd = () => setDraggingIdx(null);
  const handleDrawReset = () => { setDrawPoints(DEFAULT_DRAW); setDraggingIdx(null); };

  // Mode-specific render data — pill text, centroid, info-row place/count.
  const md = (() => {
    if (geo === 'draw') {
      // Estimated property count scales with polygon area (shoelace).
      // Density factor 0.2435 props/viewBox-unit² calibrated so the
      // DEFAULT_DRAW shape yields ~1,184 — matches the prior hardcoded
      // baseline. Pill hidden in draw mode so it doesn't obstruct the
      // handles; info row at the bottom carries the count.
      const area = Math.abs(drawPoints.reduce((s, [x1, y1], i) => {
        const [x2, y2] = drawPoints[(i + 1) % drawPoints.length];
        return s + x1 * y2 - x2 * y1;
      }, 0)) / 2;
      const count = Math.round(area * 0.2435);
      return {
        pill: 'CUSTOM',
        cx: 268, cy: 180,
        place: 'free-drawn area · drag handles to refine',
        count: count.toLocaleString('en-US'),
        showPill: false,
      };
    }
    if (geo === 'zip') {
      const z = resolveZip(zipCode) || resolveZip('10001');
      if (!z) return { pill: '—', cx: 268, cy: 180, place: 'no zip data', count: '—', showPill: false };
      const [cx, cy] = centroid(pathToPoints(z.d));
      return { pill: z.code, cx, cy, place: z.place, count: z.count, showPill: true };
    }
    if (geo === 'county') {
      const c = COUNTIES[countyIdx];
      return {
        pill: c.name.toUpperCase(),
        cx: 268, cy: 180,
        place: `${c.name.toLowerCase()} county · ${c.sub}, ny`,
        count: c.count,
        showPill: false, // chip grid carries the selection; no map overlay
      };
    }
    // state mode
    const states = (window.US_STATES || []);
    const s = states[stateIdx] || { code: 'NY', name: 'New York', count: '184,022' };
    return {
      pill: s.code,
      cx: 268, cy: 180,
      place: `${s.name.toLowerCase()} · residential`,
      count: s.count,
      showPill: false, // US map carries the selection; no center pill
    };
  })();

  const templates = [
    { id: 'cash-offer', name: 'Cash offer',      vertical: 'Real estate' },
    { id: 'probate',    name: 'Probate',         vertical: 'Real estate' },
    { id: 'winback',    name: 'Cart winback',    vertical: 'Shopify' },
    { id: 'thanks',     name: 'Thank-you',       vertical: 'Shopify' },
  ];

  // ── TABS ───────────────────────────────────────────────────────────────────
  const TABS = [
    { id: 'audience', n: '01', label: 'Audience',  eyebrow: 'Interactive · click to explore' },
    { id: 'designer', n: '02', label: 'Designer',  eyebrow: 'Designer · live preview' },
    { id: 'tracking', n: '03', label: 'Tracking',  eyebrow: 'Dashboard · sending' },
  ];
  const active = TABS.find(o => o.id === tab);
  const total = 2047;

  return (
    <div className="sv-hero-demo" style={{
      background: 'linear-gradient(180deg, color-mix(in srgb, var(--sv-paper) 70%, var(--sv-ash)) 0%, color-mix(in srgb, var(--sv-paper) 30%, var(--sv-ash)) 100%)',
      border: '1px solid var(--sv-ash)', borderRadius: 'var(--sv-radius-lg)', padding: 28,
      height: 700, display: 'flex', flexDirection: 'column', overflow: 'hidden',
    }}>
      {/* Top tab bar — segmented control */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 14 }}>
        <div style={{ display: 'flex', gap: 4, padding: 4, background: 'var(--sv-bg-elevated)', borderRadius: 'var(--sv-radius-md)', border: '1px solid var(--sv-ash)' }}>
          {TABS.map(o => (
            <button key={o.id} onClick={() => setTab(o.id)}
              className="sv-tab sv-touch-target"
              aria-pressed={tab === o.id}
              style={{
              fontFamily: 'var(--sv-font-body)', fontSize: 13, fontWeight: 600,
              padding: '8px 14px', borderRadius: 'var(--sv-radius-sm)', border: 'none',
              background: tab === o.id ? 'var(--sv-pitch)' : undefined,
              color: tab === o.id ? 'var(--sv-paper)' : 'var(--sv-pitch)',
              cursor: 'pointer', whiteSpace: 'nowrap',
              display: 'inline-flex', alignItems: 'center', gap: 8,
            }}>
              <span style={{
                fontFamily: 'var(--sv-font-mono)', fontSize: 11, fontWeight: 500,
                opacity: tab === o.id ? 0.65 : 0.55,
              }}>{o.n}</span>
              {o.label}
            </button>
          ))}
        </div>
        <window.SVMicroLabel>{active.eyebrow}</window.SVMicroLabel>
      </div>

      {/* ── AUDIENCE TAB — NYC map with overlay polygon + center pill ─────── */}
      {tab === 'audience' && (
        <div style={{ marginTop: 20, background: 'var(--sv-bg-elevated)', border: '1px solid var(--sv-ash)', borderRadius: 'var(--sv-radius-md)', overflow: 'hidden',
          flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
          {/* Top segmented tabs */}
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', borderBottom: '1px solid var(--sv-ash)' }}>
            {['draw', 'zip', 'county', 'state'].map(mode => {
              const on = geo === mode;
              return (
                <button key={mode} onClick={() => setGeo(mode)}
                  className="sv-tab sv-tab--underline sv-touch-target"
                  aria-pressed={on}
                  style={{
                  fontFamily: 'var(--sv-font-body)', fontSize: 13,
                  fontWeight: on ? 600 : 500,
                  padding: '14px 0', border: 'none',
                  borderBottom: `2px solid ${on ? 'var(--sv-volt)' : 'transparent'}`,
                  background: 'transparent', cursor: 'pointer',
                  color: on ? 'var(--sv-pitch)' : 'var(--sv-stone)',
                  letterSpacing: '-0.005em',
                }}>{mode}</button>
              );
            })}
          </div>

          {/* Canvas — mode-conditional rendering.
              draw/zip: real NYC SVG (from nyc-svg.jsx) — Manhattan ZIPs +
                       surrounding-borough context, projected from NYC OpenData
              county:    NY-metro chip-grid picker
              state:     real US states SVG map (from us-states.jsx) */}
          {(geo === 'draw' || geo === 'zip') && (
            <div style={{ position: 'relative', background: 'var(--sv-paper)',
              flex: 1, minHeight: 0, display: 'flex' }}>
              <svg viewBox={(typeof window !== 'undefined' && window.NYC_MAP_VIEWBOX) || '0 0 536 360'}
                preserveAspectRatio="xMidYMid meet"
                onMouseMove={handleSVGMouseMove}
                onMouseUp={handleSVGMouseUp}
                onMouseLeave={handleSVGMouseUp}
                onTouchMove={handleSVGTouchMove}
                onTouchEnd={handleSVGTouchEnd}
                onTouchCancel={handleSVGTouchEnd}
                style={{ display: 'block', width: '100%', height: '100%',
                  touchAction: geo === 'draw' ? 'none' : 'auto',
                  cursor: draggingIdx !== null ? 'grabbing' : 'default' }}>

                {/* ALL NYC ZIPS — Manhattan + surrounding boroughs as a unified
                    layer. In draw mode they're a plain neutral background; in
                    zip mode every ZIP is clickable and the selected one fills
                    volt. No special treatment for the labeled-16; all ZIPs read
                    the same way visually. */}
                {ALL_ZIPS_LIST.map(z => {
                  const isSelected = geo === 'zip' && z.code === zipCode;
                  return (
                    <path key={z.code} d={z.d}
                      fill={isSelected ? 'color-mix(in srgb, var(--sv-volt) 35%, transparent)' : 'var(--sv-bg-elevated)'}
                      stroke={isSelected ? 'var(--sv-volt)' : 'var(--sv-ash)'}
                      strokeWidth={isSelected ? 2 : 0.5}
                      strokeOpacity={isSelected ? 1 : 0.6}
                      vectorEffect="non-scaling-stroke"
                      onClick={geo === 'zip' ? (e) => { e.stopPropagation(); setZipCode(z.code); } : undefined}
                      style={{ cursor: geo === 'zip' ? 'pointer' : 'default',
                        transition: 'all 280ms var(--sv-ease)' }}/>
                  );
                })}

                {/* DRAW — draggable polygon handles on top. Each visible
                    handle has an invisible larger circle behind it so touch
                    targets meet ≥44 CSS-px even after the 536×360 viewBox
                    is scaled to a narrow phone width. The visible handle
                    keeps its existing 6/7-radius motion. */}
                {geo === 'draw' && (
                  <g>
                    <polygon points={drawPoints.map(p => p.join(',')).join(' ')}
                      fill="color-mix(in srgb, var(--sv-volt) 30%, transparent)"
                      stroke="var(--sv-volt)" strokeWidth="2.5"
                      strokeLinejoin="miter" vectorEffect="non-scaling-stroke"
                      style={{ pointerEvents: 'none' }}/>
                    {drawPoints.map(([x, y], i) => (
                      <g key={i}>
                        {/* Invisible hit-target. r=28 in the 536 viewBox →
                            ~29 CSS px on a 280px-wide phone container, ~75
                            on desktop. Doesn't fully clear 44 CSS px on
                            the smallest viewports without overlapping the
                            neighbor handles in DEFAULT_DRAW, but ~5×
                            the visible-handle area is a substantial win
                            over the prior 6/7-radius hit. */}
                        <circle cx={x} cy={y} r={28}
                          fill="transparent"
                          onMouseDown={(e) => { e.stopPropagation(); setDraggingIdx(i); }}
                          onTouchStart={(e) => { e.stopPropagation(); setDraggingIdx(i); }}
                          style={{ cursor: draggingIdx === i ? 'grabbing' : 'grab' }}/>
                        <circle cx={x} cy={y} r={draggingIdx === i ? 7 : 6}
                          fill="var(--sv-paper)" stroke="var(--sv-volt)" strokeWidth="2.5"
                          vectorEffect="non-scaling-stroke"
                          style={{ pointerEvents: 'none',
                            transition: 'r 120ms var(--sv-ease)' }}/>
                      </g>
                    ))}
                  </g>
                )}

                {/* Center pill — only in zip mode, sits on the selected ZIP */}
                {md.showPill && (() => {
                  const w = Math.max(46, md.pill.length * 8 + 18);
                  const h = 26;
                  return (
                    <g transform={`translate(${md.cx}, ${md.cy})`}
                      style={{ pointerEvents: 'none', transition: 'transform 280ms var(--sv-ease)' }}>
                      <rect x={-w/2} y={-h/2} width={w} height={h} rx={h/2} fill="var(--sv-pitch)"/>
                      <circle cx={-w/2 + 8} cy={-h/2 + 6} r="2" fill="var(--sv-volt)"/>
                      <text x="0" y="4" textAnchor="middle"
                        fontFamily="var(--sv-font-mono)" fontSize="12" fontWeight="500"
                        fill="var(--sv-paper)" letterSpacing="-0.005em">
                        {md.pill}
                      </text>
                    </g>
                  );
                })()}
              </svg>

              {/* Draw mode — reset button overlay */}
              {geo === 'draw' && (
                <button onClick={handleDrawReset} aria-label="Reset drawn polygon"
                  className="sv-touch-target"
                  style={{
                    position: 'absolute', top: 8, right: 8, zIndex: 1,
                    fontFamily: 'var(--sv-font-mono)', fontSize: 11, fontWeight: 600,
                    letterSpacing: '0.08em', textTransform: 'uppercase',
                    padding: '6px 10px', borderRadius: 'var(--sv-radius-sm)',
                    border: '1px solid var(--sv-ash)', background: 'var(--sv-bg-elevated)',
                    color: 'var(--sv-pitch)', cursor: 'pointer',
                  }}>Reset</button>
              )}
            </div>
          )}

          {/* COUNTY mode — NY-metro chip-grid picker. 8 counties as cells in a
              4×2 grid that fills the module height; click to select. */}
          {geo === 'county' && (
            <div className="sv-grid-stack-2" style={{ background: 'var(--sv-paper)', padding: 24,
              display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)',
              gridTemplateRows: 'repeat(2, 1fr)', gap: 12,
              flex: 1, minHeight: 0 }}>
              {COUNTIES.map((c, i) => (
                <button key={c.code} onClick={() => setCountyIdx(i)}
                  aria-pressed={i === countyIdx}
                  className="sv-tab sv-tab--outlined sv-touch-target"
                  style={{
                    padding: '20px 18px',
                    borderRadius: 'var(--sv-radius-md)',
                    border: `1px solid ${i === countyIdx ? 'var(--sv-pitch)' : 'var(--sv-ash)'}`,
                    background: i === countyIdx ? 'var(--sv-pitch)' : undefined,
                    color: i === countyIdx ? 'var(--sv-paper)' : 'var(--sv-pitch)',
                    cursor: 'pointer', textAlign: 'left', fontFamily: 'inherit',
                    display: 'flex', flexDirection: 'column', justifyContent: 'space-between',
                  }}>
                  <div>
                    <div style={{ fontFamily: 'var(--sv-font-display)', fontSize: 16, fontWeight: 600, letterSpacing: '-0.01em' }}>
                      {c.name}
                    </div>
                    <div style={{ fontFamily: 'var(--sv-font-mono)', fontSize: 10, opacity: 0.6, marginTop: 4, letterSpacing: '0.04em' }}>
                      {c.sub}
                    </div>
                  </div>
                  <div style={{ fontFamily: 'var(--sv-font-mono)', fontSize: 15, fontWeight: 600,
                    color: i === countyIdx ? 'var(--sv-paper)' : 'var(--sv-volt)' }}>
                    {c.count}
                  </div>
                </button>
              ))}
            </div>
          )}

          {/* STATE mode — real US states SVG from window.US_STATES (loaded via
              us-states.jsx). Each state is a clickable path; selected fills
              volt via inline style, others get .us-state class default. A
              name pill positioned via getBBox sits over the selected state. */}
          {geo === 'state' && (
            <div style={{ background: 'var(--sv-paper)', padding: '20px 24px',
              flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
              <svg viewBox={(typeof window !== 'undefined' && window.US_MAP_VIEWBOX) || '0 0 959 593'}
                style={{ width: '100%', height: '100%', display: 'block' }}>
                {((typeof window !== 'undefined' && window.US_STATES) || []).map((s, i) => (
                  <path key={s.code} d={s.d}
                    ref={i === stateIdx ? selectedStateRef : null}
                    className="us-state"
                    aria-pressed={i === stateIdx}
                    onClick={() => setStateIdx(i)}
                    style={i === stateIdx ? { fill: 'var(--sv-volt)', stroke: 'var(--sv-volt)', strokeWidth: 1 } : undefined}>
                    <title>{s.name}</title>
                  </path>
                ))}
                {/* Selected-state name pill, positioned at the state's bbox center */}
                {stateLabelPos && (() => {
                  const name = ((window.US_STATES || [])[stateIdx] || {}).name || '';
                  const w = Math.max(60, name.length * 7 + 20);
                  return (
                    <g transform={`translate(${stateLabelPos.cx}, ${stateLabelPos.cy})`}
                      style={{ pointerEvents: 'none' }}>
                      <rect x={-w/2} y="-13" width={w} height="26" rx="13" fill="var(--sv-pitch)"/>
                      <text x="0" y="4" textAnchor="middle"
                        fontFamily="var(--sv-font-mono)" fontSize="12" fontWeight="500"
                        fill="var(--sv-paper)" letterSpacing="-0.005em">
                        {name}
                      </text>
                    </g>
                  );
                })()}
              </svg>
            </div>
          )}

          {/* Bottom info row */}
          <div style={{
            padding: '14px 18px', borderTop: '1px solid var(--sv-ash)',
            display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
          }}>
            <span style={{ fontFamily: 'var(--sv-font-display)', fontSize: 16, fontWeight: 500, color: 'var(--sv-pitch)', letterSpacing: '-0.02em' }}>
              {md.place}
            </span>
            <span style={{ fontFamily: 'var(--sv-font-mono)', fontSize: 14, color: 'var(--sv-pitch)' }}>
              <span style={{ color: 'var(--sv-volt)', fontWeight: 600 }}>{md.count}</span>{' '}
              properties found
            </span>
          </div>
        </div>
      )}

      {/* ── DESIGNER TAB ─────────────────────────────────────────────────── */}
      {tab === 'designer' && (
        <div style={{ marginTop: 20, flex: 1, display: 'flex', flexDirection: 'column' }}>
          <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
            <div style={{ display: 'flex', gap: 6, padding: 4, background: 'var(--sv-bg-elevated)', borderRadius: 'var(--sv-radius-pill)', border: '1px solid var(--sv-ash)' }}>
              {['front', 'back'].map(s => (
                <button key={s} onClick={() => setSide(s)}
                  className="sv-tab sv-touch-target"
                  aria-pressed={side === s}
                  style={{
                  fontFamily: 'var(--sv-font-body)', fontSize: 12, fontWeight: 600,
                  padding: '6px 14px', borderRadius: 'var(--sv-radius-pill)', border: 'none',
                  background: side === s ? 'var(--sv-pitch)' : undefined,
                  color: side === s ? 'var(--sv-paper)' : 'var(--sv-stone)',
                  cursor: 'pointer', textTransform: 'capitalize',
                }}>{s}</button>
              ))}
            </div>
          </div>
          <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <div style={{ position: 'relative' }}>
              <div style={{ position: 'absolute', inset: -16, border: '1px dashed var(--sv-pitch-18)', borderRadius: 'var(--sv-radius-md)', pointerEvents: 'none' }}/>
              <div style={{
                position: 'absolute', top: -24, left: -16,
                fontFamily: 'var(--sv-font-mono)', fontSize: 9, color: 'var(--sv-stone)', letterSpacing: '0.08em',
              }}>BLEED · 0.125 in</div>
              <window.SVPostcard variant={variant} side={side} width={Math.min(500, Math.max(280, winW - 120))}/>
            </div>
          </div>
          <div>
            <window.SVMicroLabel>TEMPLATE</window.SVMicroLabel>
            <div style={{ marginTop: 8, display: 'flex', gap: 6, flexWrap: 'wrap' }}>
              {templates.map(tpl => (
                <button key={tpl.id} onClick={() => setVariant(tpl.id)}
                  className="sv-tab sv-tab--outlined sv-touch-target"
                  aria-pressed={variant === tpl.id}
                  style={{
                  fontFamily: 'var(--sv-font-body)', fontSize: 12, fontWeight: 500,
                  padding: '8px 12px', borderRadius: 'var(--sv-radius-sm)',
                  border: `1px solid ${variant === tpl.id ? 'var(--sv-pitch)' : 'var(--sv-ash)'}`,
                  background: variant === tpl.id ? 'var(--sv-pitch)' : undefined,
                  color: variant === tpl.id ? 'var(--sv-paper)' : 'var(--sv-pitch)',
                  cursor: 'pointer', display: 'inline-flex', alignItems: 'center', gap: 8,
                }}>
                  <span style={{ fontFamily: 'var(--sv-font-mono)', fontSize: 9, opacity: 0.65, letterSpacing: '0.08em', textTransform: 'uppercase' }}>{tpl.vertical}</span>
                  {tpl.name}
                </button>
              ))}
            </div>
          </div>
        </div>
      )}

      {/* ── TRACKING TAB ─────────────────────────────────────────────────── */}
      {tab === 'tracking' && (
        <div style={{ marginTop: 20 }}>
          {/* Campaign header */}
          <div style={{ background: 'var(--sv-bg-elevated)', border: '1px solid var(--sv-ash)', borderRadius: 'var(--sv-radius-md)', padding: 16 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 14 }}>
              <div>
                <window.SVMicroLabel>CMP-2847 · PROBATE · MANHATTAN JUNE</window.SVMicroLabel>
                <div style={{ marginTop: 4, fontFamily: 'var(--sv-font-display)', fontSize: 18, fontWeight: 500, letterSpacing: '-0.02em', color: 'var(--sv-pitch)' }}>
                  Cash offer · ZIP 10001 Chelsea
                </div>
              </div>
              <window.SVPill color="var(--sv-volt)" bg="color-mix(in srgb, var(--sv-volt) 8%, transparent)" style={{ color: 'var(--sv-volt)' }}>SENDING</window.SVPill>
            </div>

            {/* Big delivered counter + progress */}
            <div style={{ display: 'flex', alignItems: 'baseline', gap: 10 }}>
              <window.SVMono size={42} weight={500} style={{ letterSpacing: '-0.03em', lineHeight: 1 }}>
                {delivered.toLocaleString()}
              </window.SVMono>
              <span style={{ fontSize: 13, color: 'var(--sv-stone)' }}>
                of <window.SVMono size={12}>{total.toLocaleString()}</window.SVMono> delivered
              </span>
            </div>
            <div style={{ position: 'relative', marginTop: 12, height: 6, background: 'var(--sv-ash)', borderRadius: 'var(--sv-radius-pill)', overflow: 'hidden' }}>
              <div style={{
                position: 'absolute', left: 0, top: 0, bottom: 0,
                width: `${(delivered / total) * 100}%`,
                background: 'var(--sv-volt)', borderRadius: 'var(--sv-radius-pill)',
                transition: 'width 1200ms var(--sv-ease)',
              }}/>
            </div>
            <div style={{ marginTop: 6, display: 'flex', justifyContent: 'space-between' }}>
              <window.SVMono size={11} color="var(--sv-stone)">{((delivered / total) * 100).toFixed(1)}% delivered</window.SVMono>
              <window.SVMono size={11} color="var(--sv-stone)">avg 3.2 d in transit</window.SVMono>
            </div>
          </div>

          {/* Breakdown table */}
          <div style={{ marginTop: 10, background: 'var(--sv-bg-elevated)', border: '1px solid var(--sv-ash)', borderRadius: 'var(--sv-radius-md)', overflow: 'hidden', fontFamily: 'var(--sv-font-mono)', fontSize: 12 }}>
            {[
              { dot: 'var(--sv-delivered)',     t: 'delivered',     c: delivered.toLocaleString(), m: `${((delivered/total)*100).toFixed(1)}%` },
              { dot: 'var(--sv-in-transit)',    t: 'in transit',    c: '152',  m: '7.4%'  },
              { dot: 'var(--sv-review)',        t: 'returning',     c: '36',   m: '1.8%'  },
              { dot: 'var(--sv-undeliverable)', t: 'undeliverable', c: '12',   m: '0.5%'  },
            ].map((r, i) => (
              <div key={r.t} style={{
                display: 'grid', gridTemplateColumns: '14px 1fr auto auto', gap: 12, alignItems: 'center',
                padding: '11px 16px', borderTop: i ? '1px solid var(--sv-ash)' : 'none',
              }}>
                <span style={{ width: 8, height: 8, borderRadius: 'var(--sv-radius-pill)', background: r.dot, display: 'inline-block' }}/>
                <span style={{ fontFamily: 'var(--sv-font-body)', fontWeight: 500, color: 'var(--sv-pitch)' }}>{r.t}</span>
                <span style={{ color: 'var(--sv-pitch)' }}>{r.c}</span>
                <span style={{ color: 'var(--sv-stone)', minWidth: 46, textAlign: 'right' }}>{r.m}</span>
              </div>
            ))}
          </div>

          {/* Recent events feed */}
          <div style={{ marginTop: 10, background: 'var(--sv-bg-elevated)', border: '1px solid var(--sv-ash)', borderRadius: 'var(--sv-radius-md)', padding: '12px 16px' }}>
            <window.SVMicroLabel>RECENT · IMb EVENTS</window.SVMicroLabel>
            <div style={{ marginTop: 6, fontFamily: 'var(--sv-font-mono)', fontSize: 11, lineHeight: 1.85, color: 'var(--sv-pitch)' }}>
              {[
                { t: '12:08:42', addr: '247 W 28TH ST · NEW YORK NY',  s: 'delivered',        c: 'var(--sv-delivered)' },
                { t: '12:08:14', addr: '518 W 22ND ST · NEW YORK NY',  s: 'delivered',        c: 'var(--sv-delivered)' },
                { t: '12:07:51', addr: '104 EIGHTH AVE · NEW YORK NY', s: 'out for delivery', c: 'var(--sv-in-transit)' },
                { t: '12:07:30', addr: '419 W 14TH ST · NEW YORK NY',  s: 'sorted',           c: 'var(--sv-stone)' },
              ].map(e => (
                <div key={e.t} style={{ display: 'grid', gridTemplateColumns: '70px 1fr auto', gap: 14, alignItems: 'baseline' }}>
                  <span style={{ color: 'var(--sv-stone)' }}>{e.t}</span>
                  <span>{e.addr}</span>
                  <span style={{ color: e.c, textTransform: 'uppercase', letterSpacing: '0.05em', fontSize: 10, fontWeight: 600 }}>{e.s}</span>
                </div>
              ))}
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

// Mobile-only stand-in for HeroDemo. The 3-tab demo is too dense to render
// usefully under 720 px (audience map + designer canvas + tracking feed all
// compete for the same 335 px). Per the UI/UX designer proposal, on mobile
// we show a single static postcard plus a quiet `AUDIENCE › DESIGN ›
// TRACKING` caption row — the Pipeline section directly below carries the
// "tracked end-to-end" narrative on its own.
const HeroPostcardMobile = () => {
  const winW = window.useWindowWidth();
  const t = window.useT();
  const variant = t.heroCard || 'cash-offer';
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 20, marginTop: 8 }}>
      <window.SVPostcard
        variant={variant}
        side="front"
        width={Math.min(320, Math.max(240, winW - 60))}
      />
      <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
        <window.SVMicroLabel>AUDIENCE</window.SVMicroLabel>
        <window.SVArrow size={9} color="var(--sv-stone)"/>
        <window.SVMicroLabel>DESIGN</window.SVMicroLabel>
        <window.SVArrow size={9} color="var(--sv-stone)"/>
        <window.SVMicroLabel>TRACKING</window.SVMicroLabel>
      </div>
    </div>
  );
};

// Hero — split layout. Left: copy + CTAs. Right: tabbed product demo
// (desktop) or static postcard + caption (mobile, via HeroPostcardMobile).
const V2Hero = () => {
  const t = window.useT();
  const winW = window.useWindowWidth();
  const isMobile = winW <= 720;

  const HEADLINES = {
    'send-like-email':   (<>Send mail<br/>like you ship<br/>email<span style={{ color: 'var(--sv-volt)' }}>.</span></>),
    'not-painful':       (<>Direct mail,<br/>finally<br/>not painful<span style={{ color: 'var(--sv-volt)' }}>.</span></>),
    'mail-house-tab':    (<>The mail house,<br/>replaced<br/>by a tab<span style={{ color: 'var(--sv-volt)' }}>.</span></>),
    'fridge':            (<>Send something<br/>they'll keep<br/>on the fridge<span style={{ color: 'var(--sv-volt)' }}>.</span></>),
  };
  const headlineNode = HEADLINES[t.headline] || HEADLINES['send-like-email'];

  return (
    <section id="product" className="sv-section" style={{ padding: '72px 56px 64px', position: 'relative', overflow: 'hidden' }}>
      {/* Optional oversized chevron flourish behind the hero */}
      {t.heroFlourish && (
        <div aria-hidden="true" style={{
          position: 'absolute', right: -180, top: -120, opacity: 0.06,
          pointerEvents: 'none', transform: 'rotate(0deg)',
        }}>
          <window.SVMarkXL width={700} strokeWidth={9} color="var(--sv-volt)"/>
        </div>
      )}
      <div className="sv-grid-stack" style={{ position: 'relative', display: 'grid', gridTemplateColumns: '1.05fr 1fr', gap: 56, alignItems: 'center' }}>
        {/* LEFT — copy + price quote */}
        <div>
          <window.SVEyebrow color="var(--sv-volt)" style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
            <window.SVArrow size={11} color="var(--sv-volt)"/>Direct mail · self-serve
          </window.SVEyebrow>
          <h1 className="sv-hero-h1" style={{
            margin: '20px 0 0', fontFamily: 'var(--sv-font-display)', fontWeight: 500,
            fontSize: 'var(--sv-text-display-xl)', letterSpacing: '-0.04em', lineHeight: 0.96, color: 'var(--sv-pitch)',
          }}>
            {headlineNode}
          </h1>
          <p style={{ margin: '24px 0 0', maxWidth: 480, fontFamily: 'var(--sv-font-body)', fontSize: 'var(--sv-text-body-lg)', lineHeight: 1.55, color: 'var(--sv-stone)' }}>
            sendvo is a self-service platform that turns a list, a design, and a click into postcards in real mailboxes. Pricing is per-piece. No engineers, no minimums, no mail-house phone calls.
          </p>

          <div className="sv-flex-wrap" style={{ marginTop: 32, display: 'flex', gap: 12, alignItems: 'center' }}>
            <window.SVBtn variant="dark" size="lg" href="https://app.sendvo.io/signup">
              Start sending <window.SVArrow size={14} color="var(--sv-paper)"/>
            </window.SVBtn>
            <window.SVBtn variant="ghost" size="lg">See a sample send</window.SVBtn>
          </div>

          <div style={{ marginTop: 24, display: 'flex', alignItems: 'center', gap: 18, flexWrap: 'wrap' }}>
            <window.SVMono size={12} color="var(--sv-stone)" style={{ letterSpacing: '0.04em' }}>
              <span style={{ color: 'var(--sv-volt)' }}>●</span> 1,247 pieces sent in the last hour
            </window.SVMono>
            <a href="#pricing" className="sv-link" style={{ fontFamily: 'var(--sv-font-body)', fontSize: 'var(--sv-text-link)', textDecoration: 'underline' }}>Get a price for your send →</a>
          </div>
        </div>

        {/* RIGHT — tabbed product demo on desktop; static postcard + caption strip on mobile */}
        {isMobile ? <HeroPostcardMobile/> : <HeroDemo/>}
      </div>
    </section>
  );
};

// Big numbers strip — paper bg, oversized mono callouts.
const V2Numbers = () => (
  <section className="sv-section sv-section-tall" style={{ background: 'var(--sv-paper)', borderTop: '1px solid var(--sv-ash)', borderBottom: '1px solid var(--sv-ash)', padding: '64px 56px' }}>
    <div className="sv-grid-stack" style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 0 }}>
      {[
        { v: '$0.89', u: 'per piece, all-in',       n: 'Postage. Print. Verification. Tracking. No platform fee.' },
        { v: '48 hr', u: 'production turnaround',   n: 'On press in 8. Out the door in 48. Tracked from there.' },
        { v: '99.4%', u: 'address deliverability',  n: 'CASS-certified scrub before you spend a single dollar.' },
      ].map((c, i) => (
        <div key={c.v} className="sv-number-cell" style={{
          padding: '0 36px', borderLeft: i ? '1px solid var(--sv-ash)' : 'none',
          display: 'flex', flexDirection: 'column', gap: 14,
        }}>
          <window.SVMono className="sv-mono-jumbo" size={84} weight={400} color="var(--sv-pitch)" style={{ letterSpacing: '-0.04em', lineHeight: 1 }}>
            {c.v}
          </window.SVMono>
          <window.SVEyebrow color="var(--sv-volt)">{c.u}</window.SVEyebrow>
          <div style={{ fontFamily: 'var(--sv-font-body)', fontSize: 14, color: 'var(--sv-stone)', lineHeight: 1.55, maxWidth: 320 }}>{c.n}</div>
        </div>
      ))}
    </div>
  </section>
);

// Pipeline — animated send timeline. A row of stations with a chevron pulse moving down the line.
const V2Pipeline = () => {
  const t = window.useT();
  const winW = window.useWindowWidth();
  const allStations = [
    { t: 'Audience built',   m: '429 \u00b7 ZIP 10001',   time: '0:00' },
    { t: 'Designed',          m: 'merge tags · v3',  time: '0:07' },
    { t: 'Proof approved',    m: 'design-v3.pdf',    time: '0:11' },
    { t: 'Queued to press',   m: 'lot · A-2847',     time: '0:14' },
    { t: 'Printed',           m: '4-color · 6×4',    time: '8:02' },
    { t: 'Sorted to USPS',    m: 'NDC Edison NJ',    time: '11:40' },
    { t: 'In the mail',       m: 'IMb tracked',      time: '24:00' },
    { t: 'Delivered',         m: '90% within 5 d',   time: '5 d' },
  ];
  // All 8 stations render on every viewport — the mobile vertical stepper
  // (see colors_and_type.css @media ≤720) shows the full build/print/ship/
  // deliver story without horizontal scroll. The prior `winW <= 640` trim
  // dropped Designed / Proof approved / Sorted to USPS — the very beats
  // that sell the "tracked end-to-end" story.
  const stations = allStations;
  const [step, setStep] = useState(0);
  useEffect(() => {
    const id = setInterval(() => setStep(s => (s + 1) % stations.length), t.pipelineSpeed || 1400);
    return () => clearInterval(id);
  }, [t.pipelineSpeed, stations.length]);
  return (
    <section className="sv-section sv-section-tall" style={{ background: 'transparent', color: 'var(--sv-pitch)', borderTop: '1px solid var(--sv-ash)', padding: '96px 56px' }}>
      <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 36 }}>
        <div>
          <window.SVEyebrow color="var(--sv-volt)">→ What sendvo does</window.SVEyebrow>
          <window.SVSectionH2 maxWidth={760}>
            The whole stack. One bill.<br/>Tracked the whole way.
          </window.SVSectionH2>
        </div>
        <window.SVMono size={12} color="var(--sv-stone)">replay · auto</window.SVMono>
      </div>

      <div style={{
        position: 'relative', background: 'var(--sv-paper)', border: '1px solid var(--sv-ash)',
        borderRadius: 'var(--sv-radius-lg)', padding: '36px 32px',
      }}>
        {/* Brand chevrons between stations — colored volt as steps complete. No line through dots.
            Hidden on mobile (.sv-pipeline-chevron) because the grid switches to a vertical stepper
            layout there; the chevrons would float disconnected from the rotated stations. */}
        {stations.slice(0, -1).map((_, i) => {
          const filled = i < step;
          return (
            <div key={'chev-' + i} className="sv-pipeline-chevron" style={{
              position: 'absolute',
              top: 60,
              left: `calc(32px + (100% - 64px) * ${(i + 1) / 8})`,
              transform: 'translateX(-50%)',
              pointerEvents: 'none',
            }}>
              <svg width="14" height="18" viewBox="0 0 14 18" fill="none"
                strokeLinejoin="miter" strokeLinecap="butt" strokeMiterlimit="10"
                style={{ display: 'block' }}>
                <polyline points="2,3 6,9 2,15"
                  stroke={filled ? 'var(--sv-volt)' : 'var(--sv-border-strong)'}
                  strokeWidth="1.8"
                  style={{ transition: 'stroke 240ms var(--sv-ease)' }}/>
                <polyline points="7,3 11,9 7,15"
                  stroke={filled ? 'var(--sv-volt)' : 'var(--sv-border-strong)'}
                  strokeWidth="1.8"
                  style={{ transition: 'stroke 240ms var(--sv-ease)' }}/>
              </svg>
            </div>
          );
        })}
        <div className="sv-pipeline-grid" style={{ display: 'grid', gridTemplateColumns: `repeat(${stations.length}, 1fr)`, gap: 0 }}>
          {stations.map((s, i) => {
            const active = i <= step;
            const isHead = i === step;
            const connectorCompleted = i < step;
            return (
              <div key={s.t} className="sv-pipeline-station" data-completed={connectorCompleted ? 'true' : 'false'} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12, padding: '0 4px' }}>
                <window.SVMono className="sv-pipeline-time" size={10} color="var(--sv-stone)">{s.time}</window.SVMono>
                <div className="sv-pipeline-dot" style={{
                  width: 16, height: 16, borderRadius: 'var(--sv-radius-pill)',
                  background: active ? 'var(--sv-volt)' : 'var(--sv-bg-elevated)',
                  border: `2px solid ${active ? 'var(--sv-volt)' : 'var(--sv-border-strong)'}`,
                  boxShadow: isHead
                    ? '0 0 0 6px color-mix(in srgb, var(--sv-volt) 14%, transparent)'
                    : 'none',
                  boxSizing: 'border-box',
                  transition: 'all 280ms var(--sv-ease)',
                }}/>
                <div className="sv-pipeline-title" style={{
                  fontFamily: 'var(--sv-font-display)', fontWeight: 500, fontSize: 14,
                  letterSpacing: '-0.015em',
                  color: active ? 'var(--sv-pitch)' : 'var(--sv-stone)',
                  textAlign: 'center', lineHeight: 1.25, maxWidth: 110,
                  transition: 'color 280ms var(--sv-ease)',
                }}>{s.t}</div>
                <window.SVMono className="sv-pipeline-meta" size={10} color={active ? 'var(--sv-stone)' : 'var(--sv-pitch-40)'}>{s.m}</window.SVMono>
              </div>
            );
          })}
        </div>
      </div>

      <div style={{ marginTop: 28, display: 'flex', gap: 36, flexWrap: 'wrap', color: 'var(--sv-stone)', fontSize: 13 }}>
        <span><window.SVMono size={12} color="var(--sv-volt)" aria-hidden="true">●</window.SVMono> Live status for every piece, with IMb tracking.</span>
        <span className="sv-mobile-hide"><window.SVMono size={12} color="var(--sv-volt)" aria-hidden="true">●</window.SVMono> Webhooks &amp; CSV exports for your CRM.</span>
        <span className="sv-mobile-hide"><window.SVMono size={12} color="var(--sv-volt)" aria-hidden="true">●</window.SVMono> Audit log of who approved what, when.</span>
      </div>
    </section>
  );
};

// Comparison — sendvo vs Mail house vs API tool.
const V2Compare = () => {
  const winW = window.useWindowWidth();
  const isMobile = winW <= 720;
  const cols = [
    { name: 'sendvo',     vertical: 'Self-service · operator-first', sub: 'us',   highlight: true },
    { name: 'Mail house', vertical: 'Phone, email, PDFs, invoices',   sub: 'the incumbents' },
    { name: 'Mail API',   vertical: 'For engineers, not operators',   sub: 'lob, etc' },
  ];
  const rows = [
    ['Time to first send',         '< 10 min',          '2–4 weeks',          '2–3 days, with eng'],
    ['Minimum order',              '50 pieces',         '500–5,000',          '1 piece, but billed monthly'],
    ['Per-piece price',            '$0.89',             '$0.42 – $1.20',      '$0.96 – $1.40 + platform'],
    ['Pricing is public',          'yes',               'no',                 'kind of'],
    ['Drag-and-drop designer',     'yes',               'no',                 'no'],
    ['Vertical templates',         'yes',               'no',                 'no'],
    ['Address verification (CASS)', 'included',         'extra',              'included'],
    ['Piece-level tracking',       'included',          'extra · paper proof', 'included'],
    ['Engineers required',         'no',                'no',                 'yes'],
  ];
  return (
    <section className="sv-section sv-section-tall" style={{ borderTop: '1px solid var(--sv-ash)', padding: '96px 56px' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 32 }}>
        <div>
          <window.SVEyebrow>What you're choosing between</window.SVEyebrow>
          <window.SVSectionH2 maxWidth={760}>
            The market gave you two bad options.<br/>We made a third.
          </window.SVSectionH2>
        </div>
      </div>
      {isMobile ? (
        /* Mobile: per-row card stack. One card per comparison row. All 9
           rows ship (the table → cards rewrite makes them scannable
           individually). Sendvo row gets the existing volt 4% tint. No
           horizontal scroll. Per UI/UX designer proposal. */
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          {rows.map((r, ri) => (
            <div key={ri} style={{
              background: 'var(--sv-bg-elevated)',
              border: '1px solid var(--sv-ash)',
              borderRadius: 'var(--sv-radius-md)',
              padding: 16,
              display: 'flex', flexDirection: 'column', gap: 12,
            }}>
              <div style={{ fontFamily: 'var(--sv-font-display)', fontSize: 15, fontWeight: 500, letterSpacing: '-0.015em', color: 'var(--sv-pitch)' }}>
                {r[0]}
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 4, borderTop: '1px solid var(--sv-ash)', paddingTop: 12 }}>
                {r.slice(1).map((cell, ci) => (
                  <div key={ci} style={{
                    display: 'grid', gridTemplateColumns: '92px 1fr', gap: 12, alignItems: 'baseline',
                    padding: '8px 12px', borderRadius: 'var(--sv-radius-sm)',
                    background: ci === 0 ? 'color-mix(in srgb, var(--sv-volt) 6%, transparent)' : 'transparent',
                  }}>
                    <span style={{ fontFamily: 'var(--sv-font-body)', fontSize: 12, fontWeight: ci === 0 ? 600 : 500, color: ci === 0 ? 'var(--sv-pitch)' : 'var(--sv-stone)' }}>
                      {cols[ci].name}{ci === 0 && <span style={{ color: 'var(--sv-volt)' }}>.</span>}
                    </span>
                    <span style={{ fontFamily: ci === 0 ? 'var(--sv-font-mono)' : 'var(--sv-font-body)', fontSize: 13, color: ci === 0 ? 'var(--sv-pitch)' : 'var(--sv-stone)' }}>
                      {cell}
                    </span>
                  </div>
                ))}
              </div>
            </div>
          ))}
        </div>
      ) : (
        <div style={{ background: 'var(--sv-bg-elevated)', border: '1px solid var(--sv-ash)', borderRadius: 'var(--sv-radius-lg)', overflow: 'hidden' }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1.4fr repeat(3, 1fr)', borderBottom: '1px solid var(--sv-ash)' }}>
            <div style={{ padding: '20px 24px' }}>
              <window.SVEyebrow>Compare</window.SVEyebrow>
            </div>
            {cols.map(c => (
              <div key={c.name} style={{
                padding: '20px 24px', borderLeft: '1px solid var(--sv-ash)',
                background: c.highlight ? 'color-mix(in srgb, var(--sv-volt) 4%, transparent)' : 'transparent',
              }}>
                <div style={{ fontFamily: 'var(--sv-font-display)', fontSize: 22, fontWeight: 500, letterSpacing: '-0.025em', color: 'var(--sv-pitch)' }}>
                  {c.name}{c.highlight && <span style={{ color: 'var(--sv-volt)' }}>.</span>}
                </div>
                <window.SVMono size={11} color="var(--sv-stone)" style={{ letterSpacing: '0.06em' }}>{c.vertical}</window.SVMono>
              </div>
            ))}
          </div>
          {rows.map((r, ri) => (
            <div key={ri}
              style={{ display: 'grid', gridTemplateColumns: '1.4fr repeat(3, 1fr)', borderTop: ri ? '1px solid var(--sv-ash)' : 'none' }}>
              <div style={{ padding: '16px 24px', fontFamily: 'var(--sv-font-body)', fontSize: 14, color: 'var(--sv-pitch)', fontWeight: 500 }}>{r[0]}</div>
              {r.slice(1).map((cell, ci) => (
                <div key={ci} style={{
                  padding: '16px 24px', borderLeft: '1px solid var(--sv-ash)',
                  background: ci === 0 ? 'color-mix(in srgb, var(--sv-volt) 4%, transparent)' : 'transparent',
                  fontFamily: ci === 0 ? 'var(--sv-font-mono)' : 'var(--sv-font-body)',
                  fontSize: 13,
                  color: ci === 0 ? 'var(--sv-pitch)' : 'var(--sv-stone)',
                }}>{cell}</div>
              ))}
            </div>
          ))}
        </div>
      )}
    </section>
  );
};

// Use cases tabbed strip — three personas, each with a real example
const V2UseCases = () => {
  const cases = [
    {
      tag: 'Real estate',
      headline: 'Investors mailing 2,000 cash-offer cards on probate lists.',
      sub: '"We pulled the August probate filings on Monday, mailed Tuesday. Two calls back by Friday."',
      stat: '4.3%', statLabel: 'reply rate · probate, Aug 2026',
      variant: 'cash-offer',
    },
    {
      tag: 'Shopify',
      headline: 'DTC brands winning back abandoned carts with a postcard.',
      sub: '"Cards we sent for $0.89 brought back $42 each on average. Email could not touch that."',
      stat: '$42.10', statLabel: 'avg recovered · per piece',
      variant: 'winback',
    },
    {
      tag: 'Agencies',
      headline: 'Marketing agencies running mail for 14 local clients from one dashboard.',
      sub: '"We bill 30%. Our clients see proofs and tracking. Sendvo handles the paper."',
      stat: '14', statLabel: 'clients · one bill at end of month',
      variant: 'thanks',
    },
  ];
  const [i, setI] = useState(0);
  const c = cases[i];
  const winWUseCases = window.useWindowWidth();
  const isMobile = winWUseCases <= 720;
  return (
    <section id="customers" className="sv-section sv-section-tall" style={{ borderTop: '1px solid var(--sv-ash)', padding: '96px 56px' }}>
      <window.SVEyebrow>Who sends with sendvo</window.SVEyebrow>
      <window.SVSectionH2>
        Three verticals. One product.
      </window.SVSectionH2>
      <div className="sv-flex-wrap" style={{ display: 'flex', gap: 6, marginTop: 32, marginBottom: 24 }}>
        {cases.map((cs, idx) => (
          <button key={cs.tag} onClick={() => setI(idx)}
            className="sv-tab sv-tab--outlined sv-touch-target"
            aria-pressed={i === idx}
            style={{
            fontFamily: 'var(--sv-font-body)', fontSize: 13, fontWeight: 600, letterSpacing: '-0.005em',
            padding: '10px 18px', borderRadius: 'var(--sv-radius-sm)',
            border: `1px solid ${i === idx ? 'var(--sv-pitch)' : 'var(--sv-ash)'}`,
            background: i === idx ? 'var(--sv-pitch)' : undefined,
            color: i === idx ? 'var(--sv-paper)' : 'var(--sv-pitch)',
            cursor: 'pointer',
          }}>{cs.tag}</button>
        ))}
      </div>
      <div className="sv-grid-stack sv-card-pad" style={{ display: 'grid', gridTemplateColumns: '1.1fr 1fr', gap: 56, alignItems: 'center',
        background: 'var(--sv-bg-elevated)', border: '1px solid var(--sv-ash)', borderRadius: 'var(--sv-radius-lg)', padding: '40px 48px' }}>
        <div>
          <div className="sv-card-headline" style={{ fontFamily: 'var(--sv-font-display)', fontWeight: 500, fontSize: 32, letterSpacing: '-0.025em', lineHeight: 1.15, color: 'var(--sv-pitch)' }}>
            {c.headline}
          </div>
          <div style={{ marginTop: 16, fontFamily: 'var(--sv-font-body)', fontSize: 'var(--sv-text-body-md)', color: 'var(--sv-stone)', lineHeight: 1.6, fontStyle: 'normal' }}>
            {c.sub}
          </div>
          {/* Stat block — display callout on desktop, demoted to inline meta
              on mobile so the headline + quote lead the read. */}
          {isMobile ? (
            <div style={{ marginTop: 16, display: 'flex', alignItems: 'baseline', gap: 8, flexWrap: 'wrap' }}>
              <window.SVMono size={13} weight={600} color="var(--sv-volt)">{c.stat}</window.SVMono>
              <span style={{ fontFamily: 'var(--sv-font-body)', fontSize: 13, color: 'var(--sv-stone)' }}>· {c.statLabel}</span>
            </div>
          ) : (
            <div style={{ marginTop: 24, display: 'flex', alignItems: 'baseline', gap: 14 }}>
              <window.SVMono size={40} weight={500} style={{ letterSpacing: '-0.025em' }}>{c.stat}</window.SVMono>
              <span style={{ fontFamily: 'var(--sv-font-body)', fontSize: 13, color: 'var(--sv-stone)' }}>{c.statLabel}</span>
            </div>
          )}
        </div>
        {/* Postcard hidden on mobile — hero now carries the visual; this
            card focuses on the headline + quote + stat. */}
        <div className="sv-mobile-hide" style={{ display: 'flex', justifyContent: 'center' }}>
          <window.SVPostcard variant={c.variant} width={Math.min(380, Math.max(260, winWUseCases - 80))}/>
        </div>
      </div>
    </section>
  );
};

const V2Integrations = () => {
  const tools = [
    'Hubspot', 'Salesforce', 'Shopify', 'PropStream', 'Zapier', 'Make', 'Segment', 'Klaviyo',
  ];
  return (
    <section id="integrations" className="sv-section sv-section-tall" style={{ borderTop: '1px solid var(--sv-ash)', padding: '96px 56px' }}>
      <window.SVEyebrow>Integrations</window.SVEyebrow>
      <window.SVSectionH2 maxWidth={720}>
        Plugs into the tools that already hold your list.
      </window.SVSectionH2>
      <p style={{ marginTop: 16, fontFamily: 'var(--sv-font-body)', fontSize: 'var(--sv-text-body-lg)', color: 'var(--sv-stone)', maxWidth: 580, lineHeight: 1.55 }}>
        Triggered postcards from cart events, won deals, new leads, or any webhook you point at us.
      </p>
      <div className="sv-grid-stack-2 sv-card-pad" style={{
        marginTop: 32, background: 'var(--sv-paper)', border: '1px solid var(--sv-ash)', borderRadius: 'var(--sv-radius-lg)',
        padding: '40px 48px', display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 10,
      }}>
        {tools.map(t => (
          <div key={t} style={{
            background: 'var(--sv-bg-elevated)', border: '1px solid var(--sv-ash)', borderRadius: 'var(--sv-radius-md)',
            padding: '14px 16px', display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          }}>
            <span style={{ fontFamily: 'var(--sv-font-display)', fontWeight: 500, fontSize: 14, letterSpacing: '-0.02em', color: 'var(--sv-pitch)' }}>{t}</span>
            <window.SVMono size={10} color="var(--sv-delivered)">● live</window.SVMono>
          </div>
        ))}
      </div>
    </section>
  );
};

// V2Quote — moved out of the hero into its own focused section.
// Two-column: headline + reasoning on the left, the interactive calculator on the right.
const V2Quote = () => {
  const [volume, setVolume] = useState(500);
  const perPiece = 0.89;
  const total = (volume * perPiece).toFixed(2);
  const turnAroundHrs = volume <= 1000 ? 24 : volume <= 5000 ? 48 : 72;
  // Savings anchored against the *average* mail-house quote — the midpoint
  // of (cheap setup-heavy quote, premium quote). The prior baseline used
  // the low end alone, which dropped to $0 above ~1,300 pieces (mail houses
  // get cheaper per-piece at scale). Average baseline keeps savings
  // positive across the full slider — ~$560 at 500 pieces, ~$750 at 10k.
  const mailHouseLow  = volume * 0.62 + 350;
  const mailHouseHigh = volume * 1.20 + 750;
  const mailHouseAvg  = (mailHouseLow + mailHouseHigh) / 2;
  const savings       = Math.max(0, Math.round(mailHouseAvg - parseFloat(total))).toLocaleString();

  return (
    <section id="pricing" className="sv-section sv-section-tall" style={{ background: 'var(--sv-paper)', borderTop: '1px solid var(--sv-ash)', borderBottom: '1px solid var(--sv-ash)', padding: '96px 56px' }}>
      <div className="sv-grid-stack" style={{ display: 'grid', gridTemplateColumns: '0.9fr 1.1fr', gap: 56, alignItems: 'center' }}>
        <div>
          <window.SVEyebrow color="var(--sv-volt)" style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
            <window.SVArrow size={11} color="var(--sv-volt)"/>Try a quote
          </window.SVEyebrow>
          <window.SVSectionH2 style={{ margin: '20px 0 0' }}>
            See what your<br/>send costs, live<span style={{ color: 'var(--sv-volt)' }}>.</span>
          </window.SVSectionH2>
          <p style={{ marginTop: 18, maxWidth: 460, fontSize: 16, color: 'var(--sv-stone)', lineHeight: 1.55 }}>
            Drag the slider. Every number is final — postage, print, verification, tracking, all in.
          </p>
        </div>

        {/* The calculator */}
        <div className="sv-card-pad" style={{ background: 'var(--sv-bg-elevated)', border: '1px solid var(--sv-ash)', borderRadius: 'var(--sv-radius-lg)', padding: '40px 48px' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
            <window.SVEyebrow>Your send</window.SVEyebrow>
            <window.SVMono size={11} color="var(--sv-stone)">live · no signup</window.SVMono>
          </div>
          <div style={{ marginTop: 18, display: 'flex', alignItems: 'baseline', gap: 16, flexWrap: 'wrap' }}>
            <window.SVMono size={72} weight={500} style={{ letterSpacing: '-0.035em', lineHeight: 1 }}>
              ${total}
            </window.SVMono>
            <span style={{ color: 'var(--sv-stone)', fontSize: 15 }}>
              total · <window.SVMono size={13}>{volume.toLocaleString()}</window.SVMono> pieces · <window.SVMono size={13}>${perPiece.toFixed(2)}</window.SVMono> each
            </span>
          </div>
          {/* Always-visible savings line, sits right under the big total so
              there's no scrolling or column-switching to find the win. Volt
              fg + bold for emphasis; the trailing copy stays muted stone. */}
          <div style={{ marginTop: 8, fontFamily: 'var(--sv-font-body)', fontSize: 15, color: 'var(--sv-volt)', fontWeight: 600 }}>
            Save ${savings}
            <span style={{ color: 'var(--sv-stone)', fontWeight: 400, marginLeft: 6 }}>vs average mail house</span>
          </div>
          <input
            type="range" min={50} max={10000} step={50} value={volume}
            onChange={e => setVolume(+e.target.value)}
            aria-label="Send volume in pieces"
            aria-valuetext={`${volume.toLocaleString()} pieces · $${total} total · save $${savings} vs average mail house`}
            style={{ width: '100%', marginTop: 24, accentColor: 'var(--sv-volt)', height: 4 }}
          />
          <div style={{ display: 'flex', justifyContent: 'space-between', fontFamily: 'var(--sv-font-mono)', fontSize: 11, color: 'var(--sv-stone)', marginTop: 6 }}>
            <span>50</span><span>2,500</span><span>5,000</span><span>10,000</span>
          </div>
          <div style={{ marginTop: 20, paddingTop: 16, borderTop: '1px solid var(--sv-ash)', fontFamily: 'var(--sv-font-body)', fontSize: 13, color: 'var(--sv-stone)', lineHeight: 1.55 }}>
            Includes postage, print, verification, tracking · <span style={{ color: 'var(--sv-pitch)' }}>{turnAroundHrs} hr to mail</span>.
          </div>
          <div className="sv-flex-wrap" style={{ marginTop: 22, display: 'flex', gap: 10 }}>
            <window.SVBtn variant="primary" size="lg" href={`https://app.sendvo.io/signup?volume=${volume}`}>Send {volume.toLocaleString()} pieces <window.SVArrow size={14}/></window.SVBtn>
            <window.SVBtn variant="ghost" size="lg">Volume rates</window.SVBtn>
          </div>
        </div>
      </div>
    </section>
  );
};

const V2CTA = () => (
  <section className="sv-section sv-section-tall" style={{ borderTop: '1px solid var(--sv-ash)', padding: '96px 56px' }}>
    <div className="sv-flex-wrap sv-card-pad" style={{
      background: 'var(--sv-volt)', borderRadius: 'var(--sv-radius-lg)', padding: '40px 48px',
      display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 32,
    }}>
      <div>
        <window.SVEyebrow style={{ color: 'var(--sv-pitch)' }}>Ready when you are</window.SVEyebrow>
        <window.SVSectionH2 maxWidth={640}>
          Send your first 50 for free. We pay the postage.
        </window.SVSectionH2>
      </div>
      <div className="sv-flex-wrap" style={{ display: 'flex', gap: 12, flexShrink: 0 }}>
        <window.SVBtn variant="dark" size="lg" href="https://app.sendvo.io/signup">Start sending <window.SVArrow size={14} color="var(--sv-paper)"/></window.SVBtn>
        <window.SVBtn variant="light" size="lg">Book a 15-min demo</window.SVBtn>
      </div>
    </div>
  </section>
);

const V2Footer = () => (
  <footer className="sv-section" style={{ background: 'var(--sv-bg-elevated)', borderTop: '1px solid var(--sv-ash)', padding: '48px 56px 32px' }}>
    <div className="sv-flex-wrap" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 48 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <window.SVMark size={22}/>
        <window.SVWordmark size={22}/>
      </div>
      <div className="sv-flex-wrap" style={{ display: 'flex', gap: 56 }}>
        {[
          ['Product',   [['Designer', '#product'], ['Pricing', '#pricing'], ['Templates', '#customers'], ['Integrations', '#integrations']]],
          ['Use cases', [['Real estate', '#customers'], ['Shopify', '#customers'], ['Agencies', '#customers']]],
          ['Resources', [['Docs', '#'], ['Status', '#'], ['Deliverability', '#']]],
          ['Company',   [['About', '#'], ['Careers', '#'], ['Contact', '#']]],
        ].map(([title, items]) => (
          <div key={title} style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            <div style={{ fontFamily: 'var(--sv-font-body)', fontWeight: 600, fontSize: 10, letterSpacing: '0.16em', textTransform: 'uppercase', color: 'var(--sv-stone)' }}>{title}</div>
            {items.map(([label, href]) => (
              <a key={label} href={href} className="sv-link" style={{ fontSize: 'var(--sv-text-link)' }}>{label}</a>
            ))}
          </div>
        ))}
      </div>
    </div>
    <div style={{ marginTop: 32, paddingTop: 18, borderTop: '1px solid var(--sv-ash)', display: 'flex', justifyContent: 'space-between' }}>
      <window.SVMono size={11} color="var(--sv-stone)">© 2026 SendVo, Inc.</window.SVMono>
      <window.SVMono size={11} color="var(--sv-stone)">sendvo.io · CASS-certified · USPS commercial</window.SVMono>
    </div>
  </footer>
);

const V2Interactive = () => {
  const t = window.useT();
  return (
    <div style={{ background: 'transparent', color: 'var(--sv-pitch)', fontFamily: 'var(--sv-font-body)' }}>
      <a href="#main" className="sv-skip-link">Skip to main content</a>
      <V2Nav/>
      <main id="main">
        <V2Hero/>
        <V2Numbers/>
        {t.showPipeline && <V2Pipeline/>}
        {t.showCompare && <V2Compare/>}
        <V2UseCases/>
        {t.showIntegrations && <V2Integrations/>}
        <V2Quote/>
        <V2CTA/>
      </main>
      <V2Footer/>
    </div>
  );
};

window.V2Interactive = V2Interactive;
