// screens.jsx — Liberty Shoe Drive (Option 2 — Checkpoint QR Code System)
// No GPS, no continuous tracking. Users scan QR codes at fixed checkpoints
// along a known route. Distance is the sum of the legs they covered between
// scans; step count is derived from that distance. No map — just a list.

const NAVY        = '#0B1F44';
const NAVY_2      = '#122A55';
const NAVY_3      = '#1B3868';
const LIBERTY_BLU = '#003594';
const GOLD        = '#E8C28A';
const GOLD_SOFT   = '#D9B57E';
const CREAM       = '#F5F0E6';
const CREAM_DIM   = 'rgba(245, 240, 230, 0.62)';
const CREAM_FAINT = 'rgba(245, 240, 230, 0.18)';
const LINE        = 'rgba(245, 240, 230, 0.10)';
const GREEN       = '#9BE0B3';

// ─── Route definition ────────────────────────────────────────────
// 8 stations, A → H, along a fixed route. 7 legs between them.
const STATIONS = [
  { id: 'A', name: 'Liberty Stall',   sub: 'Start line' },
  { id: 'B', name: 'Centre Court',    sub: 'Checkpoint' },
  { id: 'C', name: 'Fountain Atrium', sub: 'Checkpoint' },
  { id: 'D', name: 'The Promenade',   sub: 'Checkpoint' },
  { id: 'E', name: 'Garden Terrace',  sub: 'Checkpoint' },
  { id: 'F', name: 'Skybridge',       sub: 'Checkpoint' },
  { id: 'G', name: 'Diamond Walk',    sub: 'Checkpoint' },
  { id: 'H', name: 'Liberty Finish',  sub: 'Finish line' },
];
// distance of leg i (station i → station i+1), in km. Sums to 3.16.
const LEGS_KM = [0.45, 0.38, 0.52, 0.41, 0.58, 0.36, 0.46];
const STEPS_PER_KM = 1312; // ~0.76 m stride

const legSteps = (i) => Math.round(LEGS_KM[i] * STEPS_PER_KM);

// Given the set of scanned station indices, work out which legs were
// covered: every segment between consecutive scans (sorted) is credited.
// e.g. scan A, C, F  →  legs A-B, B-C, C-D, D-E, E-F.
function computeTotals(scanned) {
  const s = [...new Set(scanned)].sort((a, b) => a - b);
  const legSet = new Set();
  for (let i = 0; i < s.length - 1; i++) {
    for (let l = s[i]; l < s[i + 1]; l++) legSet.add(l);
  }
  const legs = [...legSet].sort((a, b) => a - b).map(l => ({
    idx: l, from: STATIONS[l].id, to: STATIONS[l + 1].id,
    km: LEGS_KM[l], steps: legSteps(l),
  }));
  const km = +legs.reduce((a, b) => a + b.km, 0).toFixed(2);
  const steps = legs.reduce((a, b) => a + b.steps, 0);
  return { legs, km, steps, shoes: Math.floor(km), scannedCount: s.length };
}

// ─── Liberty brand assets ────────────────────────────────────────
const LIBERTY_ASSET = {
  white: {
    mark: '/assets/liberty-mark-white.png?v=3',
    word: '/assets/liberty-word-white.png?v=3',
    full: '/assets/liberty-full-white.png?v=3',
  },
  navy: {
    mark: '/assets/liberty-mark-navy.png?v=3',
    word: '/assets/liberty-word-navy.png?v=3',
    full: '/assets/liberty-full-navy.png?v=3',
  },
};

function LibertyMark({ size = 28, tone = 'white' }) {
  return (
    <img src={LIBERTY_ASSET[tone].mark} alt="Liberty"
         width={size} height={size}
         style={{ display: 'block', objectFit: 'contain', flexShrink: 0 }}/>
  );
}

function LibertyLockup({ size = 'sm', tagline = false, tone = 'white', align = 'horizontal' }) {
  const markH = size === 'lg' ? 60 : size === 'md' ? 44 : 30;
  const A = LIBERTY_ASSET[tone];
  const tagColor = tone === 'navy' ? 'rgba(11,31,68,0.6)' : 'rgba(245,240,230,0.7)';
  const tag = (fs) => (
    <div style={{
      fontFamily: 'Geist Mono, monospace', fontWeight: 400, fontSize: fs,
      letterSpacing: '0.2em', textTransform: 'uppercase', color: tagColor,
    }}>Do it with you</div>
  );
  if (align === 'stacked') {
    return (
      <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 10 }}>
        <img src={A.full} alt="Liberty" style={{ height: markH * 2.1, width: 'auto', display: 'block' }}/>
        {tagline && tag(markH * 0.26)}
      </div>
    );
  }
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 11 }}>
      <img src={A.mark} alt="" style={{ height: markH, width: markH, objectFit: 'contain', display: 'block', flexShrink: 0 }}/>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 5 }}>
        <img src={A.word} alt="Liberty" style={{ height: markH * 0.46, width: 'auto', display: 'block' }}/>
        {tagline && tag(markH * 0.26)}
      </div>
    </div>
  );
}

function PrimaryButton({ children, onClick, variant = 'gold', style = {} }) {
  const palette = {
    gold:    { bg: GOLD, fg: NAVY,  hover: GOLD_SOFT },
    cream:   { bg: CREAM, fg: NAVY, hover: '#EDE5D2' },
    liberty: { bg: LIBERTY_BLU, fg: CREAM, hover: '#0040AC' },
    ghost:   { bg: 'transparent', fg: CREAM, hover: 'rgba(245,240,230,0.06)', border: `1px solid ${CREAM_FAINT}` },
    dark:    { bg: NAVY_3, fg: CREAM, hover: '#274785' },
  }[variant];
  const [hover, setHover] = React.useState(false);
  return (
    <button onClick={onClick} onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      style={{
        appearance: 'none', border: palette.border || 'none',
        background: hover ? palette.hover : palette.bg, color: palette.fg,
        padding: '18px 28px', borderRadius: 999,
        fontFamily: 'Geist, sans-serif', fontWeight: 600, fontSize: 16, letterSpacing: '-0.01em',
        cursor: 'pointer', width: '100%',
        transition: 'background 0.15s ease, transform 0.1s ease',
        transform: hover ? 'translateY(-1px)' : 'translateY(0)', ...style,
      }}>
      {children}
    </button>
  );
}

function MonoLabel({ children, style = {} }) {
  return (
    <div style={{
      fontFamily: 'Geist Mono, monospace', fontSize: 10.5, letterSpacing: '0.18em',
      textTransform: 'uppercase', color: CREAM_DIM, ...style,
    }}>{children}</div>
  );
}

function BackBtn({ onClick }) {
  return (
    <button onClick={onClick} style={{
      appearance: 'none', border: `1px solid ${CREAM_FAINT}`, background: 'transparent',
      color: CREAM_DIM, padding: '8px 14px', borderRadius: 999,
      fontFamily: 'Geist Mono, monospace', fontSize: 10, letterSpacing: '0.12em',
      textTransform: 'uppercase', cursor: 'pointer',
    }}>← Back</button>
  );
}

function PhoneCanvas({ children, padTop = 64, padBottom = 36, bg, style = {} }) {
  return (
    <div style={{
      width: '100%', height: '100%', background: bg || NAVY, color: CREAM,
      paddingTop: padTop, paddingBottom: padBottom,
      display: 'flex', flexDirection: 'column', position: 'relative', overflow: 'hidden', ...style,
    }}>
      {children}
    </div>
  );
}

function ShoeIcons({ count }) {
  return (
    <div style={{ display: 'flex', gap: 4 }}>
      {[...Array(5)].map((_, i) => (
        <svg key={i} width="20" height="20" viewBox="0 0 24 24" fill="none">
          <path d="M3 16c0-2 1-3 3-3 1 0 2 1 3 1 1 0 2-1 4-1 3 0 4 1 6 1 3 0 2 4 0 4-4 0-12 0-15 0-1 0-1-1-1-2z"
                fill={i < count ? GOLD : 'transparent'} stroke={i < count ? GOLD : CREAM_FAINT}
                strokeWidth="1.5" strokeLinejoin="round"/>
        </svg>
      ))}
    </div>
  );
}

function QRPattern({ size = 132, color = NAVY }) {
  const cells = [];
  const N = 21;
  for (let y = 0; y < N; y++) {
    for (let x = 0; x < N; x++) {
      const inFinder = (cx, cy) =>
        x >= cx && x < cx + 7 && y >= cy && y < cy + 7 &&
        (x === cx || x === cx + 6 || y === cy || y === cy + 6 ||
         (x >= cx + 2 && x <= cx + 4 && y >= cy + 2 && y <= cy + 4));
      if (inFinder(0, 0) || inFinder(N - 7, 0) || inFinder(0, N - 7)) { cells.push({ x, y }); continue; }
      const nearFinder = (x < 8 && y < 8) || (x > N - 9 && y < 8) || (x < 8 && y > N - 9);
      if (nearFinder) continue;
      const r = Math.sin(x * 12.9898 + y * 78.233) * 43758.5453;
      if ((r - Math.floor(r)) > 0.52) cells.push({ x, y });
    }
  }
  const cell = size / N;
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
      {cells.map((c, i) => (
        <rect key={i} x={c.x * cell} y={c.y * cell} width={cell + 0.2} height={cell + 0.2} fill={color} rx={1}/>
      ))}
    </svg>
  );
}

// ────────────────────────────────────────────────────────────────
// QR scanner — inline camera simulation (no system permission popup)
// ────────────────────────────────────────────────────────────────
function ScannerView({ targetIdx, onDetect, onCancel, asOverlay = false }) {
  const station = STATIONS[targetIdx];
  const [phase, setPhase] = React.useState('aim'); // aim → reading → done
  React.useEffect(() => {
    if (phase === 'reading') { const t = setTimeout(() => setPhase('done'), 850); return () => clearTimeout(t); }
    if (phase === 'done')    { const t = setTimeout(() => onDetect(targetIdx), 650); return () => clearTimeout(t); }
  }, [phase]);

  const isStart = targetIdx === 0;
  const isEnd = targetIdx === STATIONS.length - 1;
  const role = isStart ? 'Start code' : isEnd ? 'Finish code' : 'Checkpoint code';

  return (
    <div style={{
      position: asOverlay ? 'absolute' : 'relative', inset: asOverlay ? 0 : 'auto',
      width: '100%', height: '100%', background: NAVY, color: CREAM, zIndex: 130,
      paddingTop: asOverlay ? 56 : 64, paddingBottom: 36,
      display: 'flex', flexDirection: 'column',
    }}>
      <div style={{ padding: '0 28px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <LibertyLockup size="sm" tagline />
        <button onClick={onCancel} style={{
          appearance: 'none', border: `1px solid ${CREAM_FAINT}`, background: 'transparent',
          color: CREAM_DIM, padding: '8px 14px', borderRadius: 999,
          fontFamily: 'Geist Mono, monospace', fontSize: 10, letterSpacing: '0.12em',
          textTransform: 'uppercase', cursor: 'pointer',
        }}>✕ Cancel</button>
      </div>

      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: '0 28px' }}>
        <MonoLabel style={{ marginBottom: 14 }}>Scanning · {role}</MonoLabel>

        {/* camera viewport */}
        <div style={{
          position: 'relative', borderRadius: 26, overflow: 'hidden',
          height: 320, border: `1px solid ${LINE}`,
          background: `radial-gradient(120% 80% at 30% 20%, ${NAVY_3} 0%, #081530 70%)`,
        }}>
          {/* faux camera depth blobs */}
          <div style={{ position: 'absolute', top: -30, left: -20, width: 160, height: 160, borderRadius: '50%', background: 'rgba(255,255,255,0.04)', filter: 'blur(20px)' }}/>
          <div style={{ position: 'absolute', bottom: -40, right: -10, width: 180, height: 180, borderRadius: '50%', background: 'rgba(232,194,138,0.06)', filter: 'blur(24px)' }}/>

          {/* the QR "in frame" */}
          <div style={{
            position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <div style={{
              background: CREAM, borderRadius: 14, padding: 14,
              opacity: phase === 'done' ? 1 : 0.9,
              transform: phase === 'reading' ? 'scale(1.02)' : 'scale(1)',
              transition: 'transform 0.4s ease',
              boxShadow: '0 10px 30px rgba(0,0,0,0.4)',
            }}>
              <QRPattern size={150} color={NAVY}/>
            </div>
          </div>

          {/* corner brackets */}
          {[['top','left'],['top','right'],['bottom','left'],['bottom','right']].map(([v,h],i) => (
            <div key={i} style={{
              position: 'absolute', [v]: 26, [h]: 26, width: 34, height: 34,
              borderTop: v==='top' ? `3px solid ${GOLD}` : 'none',
              borderBottom: v==='bottom' ? `3px solid ${GOLD}` : 'none',
              borderLeft: h==='left' ? `3px solid ${GOLD}` : 'none',
              borderRight: h==='right' ? `3px solid ${GOLD}` : 'none',
              borderRadius: 6,
            }}/>
          ))}

          {/* scan line */}
          {phase !== 'done' && (
            <div style={{
              position: 'absolute', left: 30, right: 30, height: 2,
              background: `linear-gradient(90deg, transparent, ${GOLD}, transparent)`,
              boxShadow: `0 0 12px ${GOLD}`,
              animation: 'scanline 1.8s ease-in-out infinite',
            }}/>
          )}

          {/* detected overlay */}
          {phase === 'done' && (
            <div style={{
              position: 'absolute', inset: 0, background: 'rgba(11,31,68,0.78)',
              backdropFilter: 'blur(2px)', display: 'flex', flexDirection: 'column',
              alignItems: 'center', justifyContent: 'center', gap: 12,
            }}>
              <div style={{
                width: 64, height: 64, borderRadius: '50%', background: GREEN,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>
                <svg width="30" height="24" viewBox="0 0 30 24"><path d="M2 13l9 8L28 3" stroke={NAVY} strokeWidth="4" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
              </div>
              <div style={{ fontFamily: 'Bricolage Grotesque, serif', fontSize: 26, fontWeight: 600, letterSpacing: '-0.02em' }}>
                Station {station.id}
              </div>
              <div style={{ color: CREAM_DIM, fontSize: 14 }}>{station.name}</div>
            </div>
          )}
        </div>

        <div style={{ marginTop: 18, textAlign: 'center', fontSize: 13, color: CREAM_DIM, lineHeight: 1.5 }}>
          {phase === 'aim' && <>Point your camera at the <b style={{ color: CREAM }}>Station {station.id}</b> code at {station.name}.</>}
          {phase === 'reading' && <>Reading code…</>}
          {phase === 'done' && <>Checkpoint logged.</>}
        </div>
        <div style={{ marginTop: 6, textAlign: 'center' }}>
          <MonoLabel style={{ color: 'rgba(245,240,230,0.4)' }}>Camera runs inline · no app · no permission popup</MonoLabel>
        </div>
      </div>

      <div style={{ padding: '0 28px', paddingBottom: 8 }}>
        {phase === 'aim'
          ? <PrimaryButton variant="gold" onClick={() => setPhase('reading')}>Scan Station {station.id}</PrimaryButton>
          : <PrimaryButton variant="dark" onClick={() => {}} style={{ opacity: 0.6, cursor: 'default' }}>
              {phase === 'reading' ? 'Reading…' : 'Logged ✓'}
            </PrimaryButton>}
      </div>

      <style>{`
        @keyframes scanline {
          0%   { top: 30px; opacity: 0.2; }
          50%  { top: 286px; opacity: 1; }
          100% { top: 30px; opacity: 0.2; }
        }
      `}</style>
    </div>
  );
}

// ────────────────────────────────────────────────────────────────
// SCREEN 1 — Landing (Draw them in)
// ────────────────────────────────────────────────────────────────
function LandingScreen({ onNext }) {
  return (
    <PhoneCanvas bg={`radial-gradient(120% 80% at 50% 10%, ${NAVY_2} 0%, ${NAVY} 60%)`}>
      <div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: 360,
        background: `linear-gradient(180deg, ${NAVY_2} 0%, ${NAVY} 100%)`, overflow: 'hidden' }}>
        <svg width="100%" height="100%" viewBox="0 0 390 360" preserveAspectRatio="xMidYMid slice" style={{ position: 'absolute', inset: 0, opacity: 0.55 }}>
          <defs><linearGradient id="pathFade" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0" stopColor={GOLD} stopOpacity="0"/><stop offset="0.4" stopColor={GOLD} stopOpacity="0.7"/><stop offset="1" stopColor={GOLD} stopOpacity="0"/>
          </linearGradient></defs>
          {[...Array(7)].map((_, i) => (
            <path key={i} d={`M-20 ${260 + i * 8} Q 80 ${180 + i * 16}, 180 ${220 + i * 6} T 420 ${160 + i * 18}`} stroke="url(#pathFade)" strokeWidth="1.2" fill="none" opacity={1 - i * 0.12}/>
          ))}
          {/* checkpoint dots along the path */}
          {[...Array(8)].map((_, i) => (
            <g key={i}>
              <circle cx={28 + i * 48} cy={250 - i * 4} r="7" fill="none" stroke={GOLD} strokeWidth="1.4" opacity={0.5}/>
              <circle cx={28 + i * 48} cy={250 - i * 4} r="2.5" fill={GOLD} opacity={0.6}/>
            </g>
          ))}
        </svg>
      </div>

      <div style={{ padding: '0 28px', position: 'relative', zIndex: 2 }}>
        <LibertyLockup size="sm" tagline />
      </div>

      <div style={{ flex: 1 }} />

      <div style={{ padding: '0 28px', position: 'relative', zIndex: 2 }}>
        <MonoLabel style={{ marginBottom: 16 }}>● Liberty Shoe Drive · Sandton · 2026</MonoLabel>
        <div style={{ fontFamily: 'Bricolage Grotesque, serif', fontWeight: 600, fontSize: 44, lineHeight: 1.02, letterSpacing: '-0.035em', textWrap: 'pretty', marginBottom: 18 }}>
          Turn your steps into something that matters.
        </div>
        <div style={{ fontSize: 15, lineHeight: 1.55, color: CREAM_DIM, maxWidth: 320, marginBottom: 36 }}>
          Scan a checkpoint at each point on the route. Every kilometre between your scans donates a pair of school shoes — no app, no GPS, no tracking.
        </div>
        <PrimaryButton variant="gold" onClick={onNext}>Scan the START code</PrimaryButton>
        <div style={{ display: 'flex', justifyContent: 'center', marginTop: 18, gap: 6 }}>
          <MonoLabel style={{ color: 'rgba(245,240,230,0.4)' }}>8 checkpoints · {LEGS_KM.reduce((a,b)=>a+b,0).toFixed(2)} km full route</MonoLabel>
        </div>
      </div>
    </PhoneCanvas>
  );
}

// ────────────────────────────────────────────────────────────────
// SCREEN 2a — Scan START (camera)
// ────────────────────────────────────────────────────────────────
function ScanStartScreen({ onDetected, onBack }) {
  return <ScannerView targetIdx={0} onDetect={() => onDetected(0)} onCancel={onBack}/>;
}

// ────────────────────────────────────────────────────────────────
// SCREEN 2b — Registration (Name, Email, POPIA opt-in)
// ────────────────────────────────────────────────────────────────
function RegisterScreen({ onNext, onBack, form, setForm }) {
  const inputStyle = {
    width: '100%', background: 'transparent', border: 'none', borderBottom: `1px solid ${CREAM_FAINT}`,
    padding: '14px 0', fontFamily: 'Bricolage Grotesque, serif', fontSize: 22, fontWeight: 500,
    color: CREAM, outline: 'none', letterSpacing: '-0.02em',
  };
  const isValid = form.name.trim().length > 1 && /@/.test(form.email) && form.consent;
  return (
    <PhoneCanvas bg={NAVY}>
      <div style={{ padding: '0 28px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <LibertyLockup size="sm" tagline />
        <BackBtn onClick={onBack}/>
      </div>
      <div style={{ padding: '0 28px', marginTop: 30, flex: 1 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 14 }}>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '4px 10px', borderRadius: 999, background: `${GREEN}1A`, border: `1px solid ${GREEN}55` }}>
            <span style={{ width: 6, height: 6, borderRadius: '50%', background: GREEN }}/>
            <span style={{ fontFamily: 'Geist Mono, monospace', fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase', color: GREEN }}>Checked in · Station A</span>
          </span>
        </div>
        <div style={{ fontFamily: 'Bricolage Grotesque, serif', fontWeight: 600, fontSize: 34, lineHeight: 1.05, letterSpacing: '-0.035em', marginBottom: 30 }}>
          Who are we walking with today?
        </div>
        <div style={{ marginBottom: 20 }}>
          <MonoLabel style={{ marginBottom: 4 }}>Your name</MonoLabel>
          <input value={form.name} onChange={e => setForm({ ...form, name: e.target.value })} placeholder="Lerato Mokoena" style={inputStyle}/>
        </div>
        <div style={{ marginBottom: 28 }}>
          <MonoLabel style={{ marginBottom: 4 }}>Email address</MonoLabel>
          <input value={form.email} onChange={e => setForm({ ...form, email: e.target.value })} placeholder="lerato@example.com" type="email" style={inputStyle}/>
        </div>
        <label style={{ display: 'flex', gap: 14, alignItems: 'flex-start', padding: '16px', borderRadius: 18, background: NAVY_2, cursor: 'pointer', border: form.consent ? `1px solid ${GOLD}` : `1px solid ${LINE}` }}>
          <input type="checkbox" checked={form.consent} onChange={e => setForm({ ...form, consent: e.target.checked })} style={{ display: 'none' }}/>
          <div style={{ width: 22, height: 22, borderRadius: 6, flexShrink: 0, background: form.consent ? GOLD : 'transparent', border: form.consent ? `1px solid ${GOLD}` : `1px solid ${CREAM_FAINT}`, display: 'flex', alignItems: 'center', justifyContent: 'center', marginTop: 2 }}>
            {form.consent && <svg width="12" height="10" viewBox="0 0 12 10" fill="none"><path d="M1 5l3.5 3.5L11 1.5" stroke={NAVY} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>}
          </div>
          <div style={{ fontSize: 13, lineHeight: 1.55, color: 'rgba(245,240,230,0.78)' }}>
            I'd like Liberty to contact me about insurance products and future activations. I can opt out anytime.
            <span style={{ color: CREAM_DIM, display: 'block', marginTop: 4, fontSize: 11.5 }}>POPIA-compliant. Stored securely. Not sold.</span>
          </div>
        </label>
      </div>
      <div style={{ padding: '0 28px', paddingBottom: 8 }}>
        <PrimaryButton variant={isValid ? 'gold' : 'dark'} onClick={() => isValid && onNext()} style={{ opacity: isValid ? 1 : 0.55, cursor: isValid ? 'pointer' : 'not-allowed' }}>
          Start the route →
        </PrimaryButton>
      </div>
    </PhoneCanvas>
  );
}

// ────────────────────────────────────────────────────────────────
// SCREEN 3 — Checkpoints (Walk the route, scan as you go) — the core
// ────────────────────────────────────────────────────────────────
function CheckpointsScreen({ scanned, onScan, onFinish, onBack, form }) {
  const [scanTarget, setScanTarget] = React.useState(null);
  const [banner, setBanner] = React.useState(null);
  const totals = computeTotals(scanned);
  const scannedSet = new Set(scanned);
  const maxScanned = scanned.length ? Math.max(...scanned) : 0;
  const endScanned = scannedSet.has(STATIONS.length - 1);
  const nextIdx = (() => { for (let i = maxScanned + 1; i < STATIONS.length; i++) if (!scannedSet.has(i)) return i; return null; })();

  // history of legs done — segments between consecutive scans, newest first
  const segments = [];
  for (let i = 1; i < scanned.length; i++) {
    const a = scanned[i - 1], b = scanned[i], lo = Math.min(a, b), hi = Math.max(a, b);
    let km = 0, steps = 0;
    for (let l = lo; l < hi; l++) { km += LEGS_KM[l]; steps += legSteps(l); }
    segments.push({ from: STATIONS[a].id, to: STATIONS[b].id, km: +km.toFixed(2), steps });
  }
  const history = [...segments].reverse();

  // progress toward the next pair (1 km = 1 pair)
  const kmToNext = +((totals.shoes + 1) - totals.km).toFixed(2);
  const fracToNext = Math.max(0, Math.min(1, totals.km - totals.shoes));

  React.useEffect(() => {
    if (!banner) return;
    const t = setTimeout(() => setBanner(null), 3600);
    return () => clearTimeout(t);
  }, [banner]);

  const handleDetect = (idx) => {
    const prev = computeTotals(scanned);
    const next = computeTotals([...scanned, idx]);
    const prevMax = scanned.length ? Math.max(...scanned) : 0;
    onScan(idx);
    setScanTarget(null);
    setBanner({
      from: STATIONS[prevMax].id, to: STATIONS[idx].id,
      legKm: +(next.km - prev.km).toFixed(2),
      legSteps: next.steps - prev.steps,
      cumKm: next.km, shoes: next.shoes,
      kmToNext: +((next.shoes + 1) - next.km).toFixed(2),
      unlocked: next.shoes > prev.shoes,
    });
  };

  return (
    <PhoneCanvas bg={NAVY} padBottom={20}>
      <div style={{ padding: '0 28px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <LibertyLockup size="sm" tagline />
        <BackBtn onClick={onBack}/>
      </div>

      {/* running totals band */}
      <div style={{ padding: '16px 28px 10px' }}>
        <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between' }}>
          <div>
            <MonoLabel style={{ marginBottom: 6 }}>Distance banked</MonoLabel>
            <div style={{ display: 'flex', alignItems: 'flex-start', fontFamily: 'Bricolage Grotesque, serif', fontWeight: 700, fontSize: 60, lineHeight: 0.85, letterSpacing: '-0.05em', fontVariantNumeric: 'tabular-nums' }}>
              <span>{totals.km.toFixed(2).split('.')[0]}</span>
              <span style={{ color: GOLD }}>.{totals.km.toFixed(2).split('.')[1]}</span>
              <span style={{ fontSize: 19, fontWeight: 500, color: CREAM_DIM, marginLeft: 6, alignSelf: 'flex-end' }}>km</span>
            </div>
          </div>
          <div style={{ textAlign: 'right' }}>
            <MonoLabel style={{ marginBottom: 6 }}>Pairs</MonoLabel>
            <div style={{ fontFamily: 'Bricolage Grotesque, serif', fontWeight: 600, fontSize: 30, color: GOLD, letterSpacing: '-0.03em', lineHeight: 1 }}>{totals.shoes}</div>
            <div style={{ marginTop: 6 }}><ShoeIcons count={Math.min(totals.shoes, 5)}/></div>
          </div>
        </div>

        {/* progress to next pair */}
        <div style={{ marginTop: 14 }}>
          <div style={{ height: 7, borderRadius: 99, background: NAVY_3, overflow: 'hidden' }}>
            <div style={{ height: '100%', width: `${fracToNext * 100}%`, borderRadius: 99, background: `linear-gradient(90deg, ${GOLD_SOFT}, ${GOLD})`, transition: 'width 0.5s ease' }}/>
          </div>
          <div style={{ marginTop: 8, display: 'flex', justifyContent: 'space-between' }}>
            <MonoLabel style={{ color: GOLD }}>{kmToNext.toFixed(2)} km to pair #{totals.shoes + 1}</MonoLabel>
            <MonoLabel style={{ color: 'rgba(245,240,230,0.4)' }}>{totals.steps.toLocaleString()} steps</MonoLabel>
          </div>
        </div>
      </div>

      {/* scan action */}
      <div style={{ padding: '4px 28px 12px' }}>
        {endScanned ? (
          <PrimaryButton variant="gold" onClick={onFinish}>Reveal my impact →</PrimaryButton>
        ) : (
          <PrimaryButton variant="gold" onClick={() => setScanTarget(nextIdx)}>
            {nextIdx === STATIONS.length - 1 ? '＋ Scan the FINISH code' : '＋ Scan a checkpoint'}
          </PrimaryButton>
        )}
      </div>

      {/* HISTORY — only the legs you've actually scanned */}
      <div style={{ padding: '0 28px 4px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <MonoLabel>Legs you've scanned</MonoLabel>
        <MonoLabel style={{ color: 'rgba(245,240,230,0.4)' }}>{history.length} leg{history.length === 1 ? '' : 's'}</MonoLabel>
      </div>
      <div style={{ flex: 1, minHeight: 0, overflowY: 'auto', padding: '6px 28px 4px' }}>
        {history.length === 0 ? (
          <div style={{ marginTop: 16, padding: '22px 18px', borderRadius: 18, border: `1px dashed ${CREAM_FAINT}`, textAlign: 'center', color: CREAM_DIM, fontSize: 13, lineHeight: 1.5 }}>
            You're checked in at <b style={{ color: CREAM }}>Station A</b>.<br/>Find the next QR code on the route and scan it to bank your first leg.
          </div>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {history.map((s, i) => (
              <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 14px', background: NAVY_2, borderRadius: 14, border: `1px solid ${LINE}` }}>
                <div style={{ width: 26, height: 26, borderRadius: '50%', background: GREEN, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                  <svg width="11" height="9" viewBox="0 0 11 9"><path d="M1 5l3 3 6-7" stroke={NAVY} strokeWidth="1.8" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
                </div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontFamily: 'Bricolage Grotesque, serif', fontWeight: 700, fontSize: 17, color: CREAM, letterSpacing: '-0.01em' }}>{s.from} → {s.to}</div>
                  <div style={{ fontFamily: 'Geist Mono, monospace', fontSize: 9.5, letterSpacing: '0.12em', textTransform: 'uppercase', color: CREAM_DIM, marginTop: 2 }}>{s.steps.toLocaleString()} steps</div>
                </div>
                <div style={{ fontFamily: 'Bricolage Grotesque, serif', fontWeight: 600, fontSize: 18, color: GOLD, fontVariantNumeric: 'tabular-nums' }}>{s.km.toFixed(2)} km</div>
              </div>
            ))}
          </div>
        )}
      </div>

      {/* finish link */}
      {segments.length >= 1 && !endScanned && (
        <div style={{ padding: '8px 28px 4px', borderTop: `1px solid ${LINE}` }}>
          <button onClick={onFinish} style={{
            width: '100%', appearance: 'none', background: 'transparent', border: 0, color: CREAM_DIM,
            fontFamily: 'Geist Mono, monospace', fontSize: 11, letterSpacing: '0.14em', textTransform: 'uppercase', cursor: 'pointer', padding: '6px',
          }}>Finish here & reveal impact →</button>
        </div>
      )}

      {/* scan-result banner */}
      {banner && (
        <div style={{ position: 'absolute', top: 52, left: 14, right: 14, zIndex: 140, animation: 'bannerIn 0.34s cubic-bezier(.2,.8,.2,1)' }}>
          <div onClick={() => setBanner(null)} style={{
            background: NAVY_2, border: `1px solid ${GOLD}66`, borderRadius: 20, padding: '15px 17px',
            boxShadow: '0 20px 50px rgba(0,0,0,0.55)', cursor: 'pointer',
          }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 10 }}>
              <span style={{ width: 22, height: 22, borderRadius: '50%', background: GREEN, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                <svg width="10" height="8" viewBox="0 0 11 9"><path d="M1 5l3 3 6-7" stroke={NAVY} strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
              </span>
              <span style={{ flex: 1, fontFamily: 'Geist Mono, monospace', fontSize: 10.5, letterSpacing: '0.14em', textTransform: 'uppercase', color: GREEN }}>Checkpoint logged</span>
              <span style={{ color: CREAM_DIM, fontSize: 14 }}>✕</span>
            </div>
            <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
              <span style={{ fontFamily: 'Bricolage Grotesque, serif', fontWeight: 700, fontSize: 38, color: GOLD, letterSpacing: '-0.04em', lineHeight: 1, fontVariantNumeric: 'tabular-nums' }}>+{banner.legKm.toFixed(2)}</span>
              <span style={{ fontSize: 14, color: CREAM_DIM }}>km on the {banner.from}→{banner.to} leg</span>
            </div>
            <div style={{ marginTop: 12, paddingTop: 12, borderTop: `1px solid ${LINE}`, display: 'flex', justifyContent: 'space-between' }}>
              <div>
                <MonoLabel style={{ marginBottom: 3 }}>Cumulative</MonoLabel>
                <div style={{ fontFamily: 'Bricolage Grotesque, serif', fontWeight: 600, fontSize: 20, color: CREAM, letterSpacing: '-0.02em' }}>{banner.cumKm.toFixed(2)} km</div>
              </div>
              <div style={{ textAlign: 'right' }}>
                <MonoLabel style={{ marginBottom: 3 }}>{banner.unlocked ? 'Just unlocked' : 'To next pair'}</MonoLabel>
                <div style={{ fontFamily: 'Bricolage Grotesque, serif', fontWeight: 600, fontSize: 20, color: banner.unlocked ? GREEN : GOLD, letterSpacing: '-0.02em' }}>
                  {banner.unlocked ? `Pair #${banner.shoes} 🎉` : `${banner.kmToNext.toFixed(2)} km`}
                </div>
              </div>
            </div>
          </div>
        </div>
      )}

      {scanTarget !== null && (
        <ScannerView asOverlay targetIdx={scanTarget} onDetect={handleDetect} onCancel={() => setScanTarget(null)}/>
      )}

      <style>{`
        @keyframes bannerIn {
          0%   { transform: translateY(-20px); opacity: 0; }
          100% { transform: translateY(0); opacity: 1; }
        }
      `}</style>
    </PhoneCanvas>
  );
}

// ────────────────────────────────────────────────────────────────
// SCREEN 4 — Results (Reveal) — distance, shoes, steps, leg list
// ────────────────────────────────────────────────────────────────
function ResultsScreen({ onShare, onDone, scanned, form }) {
  const totals = computeTotals(scanned);
  const elapsedMin = Math.max(1, Math.round(totals.km * 11));
  const pace = totals.km > 0 ? (totals.km / (elapsedMin / 60)).toFixed(1) : '0.0';
  const minValid = Math.ceil(totals.km * 6);
  const [revealed, setRevealed] = React.useState(false);
  React.useEffect(() => { const t = setTimeout(() => setRevealed(true), 350); return () => clearTimeout(t); }, []);
  const tr = (d) => ({ transform: revealed ? 'translateY(0)' : 'translateY(18px)', opacity: revealed ? 1 : 0, transition: `all 0.6s ${d}s cubic-bezier(.2,.7,.2,1)` });

  return (
    <PhoneCanvas bg={NAVY} padBottom={20}>
      <div style={{ position: 'absolute', top: -180, left: '50%', transform: 'translateX(-50%)', width: 420, height: 420, borderRadius: '50%', background: `radial-gradient(circle, ${GOLD}33 0%, transparent 60%)`, filter: 'blur(20px)', pointerEvents: 'none' }}/>
      <div style={{ padding: '0 28px' }}><LibertyLockup size="sm" tagline /></div>

      <div style={{ flex: 1, minHeight: 0, overflowY: 'auto', padding: '24px 28px 0' }}>
        <MonoLabel style={{ marginBottom: 12, ...tr(0) }}>The walk is done · {elapsedMin} min on route</MonoLabel>
        <div style={{ fontFamily: 'Bricolage Grotesque, serif', fontWeight: 600, fontSize: 40, lineHeight: 1.0, letterSpacing: '-0.04em', marginBottom: 22, ...tr(0) }}>
          Thanks for stepping up,<br/><span style={{ color: GOLD }}>{form.name.split(' ')[0] || 'friend'}.</span>
        </div>

        {/* equation */}
        <div style={{ background: NAVY_2, borderRadius: 22, padding: '22px', border: `1px solid ${LINE}`, ...tr(0.12) }}>
          <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 8, fontFamily: 'Bricolage Grotesque, serif', fontWeight: 600, fontSize: 36, letterSpacing: '-0.035em', color: CREAM, fontVariantNumeric: 'tabular-nums' }}>
            <div>{totals.km.toFixed(2)}<span style={{ fontSize: 15, color: CREAM_DIM, marginLeft: 6, fontWeight: 400 }}>km</span></div>
            <div style={{ color: CREAM_DIM, fontSize: 22 }}>=</div>
            <div style={{ color: GOLD }}>{totals.shoes}<span style={{ fontSize: 15, color: CREAM_DIM, marginLeft: 6, fontWeight: 400 }}>pair{totals.shoes===1?'':'s'}</span></div>
          </div>
          <div style={{ marginTop: 12, fontSize: 13, lineHeight: 1.55, color: CREAM_DIM }}>
            That's <b style={{ color: CREAM }}>{totals.shoes}</b> {totals.shoes === 1 ? 'child' : 'children'} walking to school in shoes that didn't exist this morning.
          </div>
        </div>

        {/* headline stats */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8, marginTop: 14, ...tr(0.2) }}>
          <MiniStat label="Steps" value={totals.steps.toLocaleString()}/>
          <MiniStat label="Legs"  value={`${totals.legs.length}/7`}/>
          <MiniStat label="Avg pace" value={`${pace}`}/>
        </div>

        {/* the LEG LIST — no map, just a list */}
        <div style={{ marginTop: 18, ...tr(0.28) }}>
          <MonoLabel style={{ marginBottom: 10 }}>Legs you completed</MonoLabel>
          <div style={{ background: NAVY_2, borderRadius: 18, border: `1px solid ${LINE}`, overflow: 'hidden' }}>
            {totals.legs.map((l, i) => (
              <div key={l.idx} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 16px', borderBottom: i < totals.legs.length - 1 ? `1px solid ${LINE}` : 'none' }}>
                <div style={{ fontFamily: 'Bricolage Grotesque, serif', fontWeight: 700, fontSize: 15, color: GOLD, width: 54 }}>{l.from} → {l.to}</div>
                <div style={{ flex: 1, fontFamily: 'Geist Mono, monospace', fontSize: 11, letterSpacing: '0.06em', color: CREAM_DIM }}>{l.steps.toLocaleString()} steps</div>
                <div style={{ fontFamily: 'Bricolage Grotesque, serif', fontWeight: 600, fontSize: 16, color: CREAM, fontVariantNumeric: 'tabular-nums' }}>{l.km.toFixed(2)} km</div>
              </div>
            ))}
            {totals.legs.length === 0 && (
              <div style={{ padding: '16px', fontSize: 13, color: CREAM_DIM }}>No legs recorded — scan at least two checkpoints.</div>
            )}
          </div>
          <div style={{ marginTop: 10, display: 'flex', alignItems: 'center', gap: 8 }}>
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '4px 10px', borderRadius: 999, background: `${GREEN}1A`, border: `1px solid ${GREEN}55` }}>
              <svg width="11" height="9" viewBox="0 0 11 9"><path d="M1 5l3 3 6-7" stroke={GREEN} strokeWidth="1.8" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
              <span style={{ fontFamily: 'Geist Mono, monospace', fontSize: 9.5, letterSpacing: '0.12em', textTransform: 'uppercase', color: GREEN }}>Validated</span>
            </span>
            <MonoLabel style={{ color: 'rgba(245,240,230,0.4)', fontSize: 9.5 }}>Time-stamped · under {minValid} min flags for review</MonoLabel>
          </div>
        </div>
      </div>

      <div style={{ padding: '14px 28px 8px', display: 'flex', flexDirection: 'column', gap: 10, borderTop: `1px solid ${LINE}` }}>
        <PrimaryButton variant="gold" onClick={onShare}>Share your walk</PrimaryButton>
        <PrimaryButton variant="ghost" onClick={onDone}>I'll walk again</PrimaryButton>
      </div>
    </PhoneCanvas>
  );
}

function MiniStat({ label, value }) {
  return (
    <div style={{ background: NAVY_2, borderRadius: 14, padding: '12px 8px', border: `1px solid ${LINE}`, textAlign: 'center' }}>
      <div style={{ fontFamily: 'Bricolage Grotesque, serif', fontSize: 18, fontWeight: 600, color: CREAM, letterSpacing: '-0.02em', marginBottom: 3, fontVariantNumeric: 'tabular-nums' }}>{value}</div>
      <div style={{ fontFamily: 'Geist Mono, monospace', fontSize: 9, letterSpacing: '0.16em', textTransform: 'uppercase', color: CREAM_DIM }}>{label}</div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────────
// SCREEN 5 — Share
// ────────────────────────────────────────────────────────────────
function ShareScreen({ onDone, onBack, scanned, form }) {
  const totals = computeTotals(scanned);
  const [sent, setSent] = React.useState(null);
  const channels = [
    { id: 'ig', name: 'Instagram', color: '#E1306C' },
    { id: 'wa', name: 'WhatsApp', color: '#25D366' },
    { id: 'x',  name: 'X / Twitter', color: '#000' },
    { id: 'fb', name: 'Facebook', color: '#1877F2' },
    { id: 'tt', name: 'TikTok', color: '#000' },
    { id: 'lk', name: 'Copy link', color: NAVY_3 },
  ];
  return (
    <PhoneCanvas bg={NAVY}>
      <div style={{ padding: '0 28px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <BackBtn onClick={onBack}/>
        <LibertyLockup size="sm" tagline />
      </div>
      <div style={{ padding: '30px 28px 0', flex: 1, display: 'flex', flexDirection: 'column' }}>
        <MonoLabel style={{ marginBottom: 12 }}>Tell the world</MonoLabel>
        <div style={{ fontFamily: 'Bricolage Grotesque, serif', fontWeight: 600, fontSize: 32, lineHeight: 1.05, letterSpacing: '-0.035em', marginBottom: 22 }}>
          Get a friend to walk next.
        </div>
        <div style={{ background: `linear-gradient(140deg, ${NAVY_2} 0%, ${NAVY} 100%)`, borderRadius: 22, padding: 22, border: `1px solid ${LINE}`, position: 'relative', overflow: 'hidden', marginBottom: 18 }}>
          <div style={{ position: 'absolute', top: -40, right: -40, width: 200, height: 200, borderRadius: '50%', background: `radial-gradient(circle, ${GOLD}33 0%, transparent 70%)` }}/>
          <LibertyLockup size="sm" tagline />
          <div style={{ fontFamily: 'Bricolage Grotesque, serif', fontWeight: 700, fontSize: 52, lineHeight: 0.95, letterSpacing: '-0.045em', marginTop: 18, marginBottom: 4, fontVariantNumeric: 'tabular-nums' }}>
            {totals.km.toFixed(2)}<span style={{ color: GOLD }}>km</span>
          </div>
          <div style={{ fontSize: 14, color: CREAM_DIM, marginBottom: 6 }}>= {totals.shoes} pair{totals.shoes===1?'':'s'} of school shoes</div>
          <div style={{ fontSize: 12, color: 'rgba(245,240,230,0.5)', marginBottom: 16 }}>{totals.steps.toLocaleString()} steps · {totals.legs.length} legs walked</div>
          <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', fontFamily: 'Geist Mono, monospace', fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase', color: GOLD }}>
            <span>#DoItWithYou</span><span style={{ color: CREAM_DIM }}>· #LibertyShoeDrive</span>
          </div>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10 }}>
          {channels.map(c => (
            <button key={c.id} onClick={() => setSent(c.id)} style={{ appearance: 'none', border: `1px solid ${LINE}`, background: sent === c.id ? `${GOLD}22` : NAVY_2, padding: '14px 8px', borderRadius: 16, cursor: 'pointer', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8, transition: 'all 0.15s' }}>
              <div style={{ width: 36, height: 36, borderRadius: 10, background: c.color, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontSize: 13, fontWeight: 700 }}>{c.name[0]}</div>
              <div style={{ fontFamily: 'Geist, sans-serif', fontSize: 11, color: sent === c.id ? GOLD : CREAM_DIM, fontWeight: 500 }}>{sent === c.id ? 'Shared ✓' : c.name}</div>
            </button>
          ))}
        </div>
      </div>
      <div style={{ padding: '18px 28px 8px' }}>
        <PrimaryButton variant={sent ? 'gold' : 'ghost'} onClick={onDone}>{sent ? "I'm done — thanks for walking" : 'Skip & finish'}</PrimaryButton>
      </div>
    </PhoneCanvas>
  );
}

// ────────────────────────────────────────────────────────────────
// SCREEN 6 — Final thank-you
// ────────────────────────────────────────────────────────────────
function DoneScreen({ onRestart, scanned, form }) {
  const totals = computeTotals(scanned);
  return (
    <PhoneCanvas bg={`radial-gradient(120% 80% at 50% 80%, ${NAVY_2} 0%, ${NAVY} 60%)`}>
      <div style={{ padding: '0 28px' }}><LibertyLockup size="sm" tagline /></div>
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: '0 28px' }}>
        <div style={{ fontFamily: 'Bricolage Grotesque, serif', fontWeight: 600, fontSize: 50, lineHeight: 0.98, letterSpacing: '-0.04em', marginBottom: 22 }}>
          Thank you<br/>for stepping<br/>up<span style={{ color: GOLD }}>.</span>
        </div>
        <div style={{ fontSize: 15, lineHeight: 1.55, color: CREAM_DIM, marginBottom: 32, maxWidth: 320 }}>
          {form.name.split(' ')[0] || 'You'} walked {totals.km.toFixed(2)} km across {totals.legs.length} leg{totals.legs.length===1?'':'s'} and Liberty donated {totals.shoes} pair{totals.shoes===1?'':'s'} of school shoes. A confirmation is on its way to {form.email || 'your email'}.
        </div>
        <div style={{ padding: '18px 0', borderTop: `1px solid ${LINE}`, borderBottom: `1px solid ${LINE}`, display: 'flex', justifyContent: 'space-between' }}>
          <div><MonoLabel style={{ marginBottom: 4 }}>Today's drive</MonoLabel><div style={{ fontFamily: 'Bricolage Grotesque, serif', fontSize: 28, fontWeight: 600, letterSpacing: '-0.03em' }}>3,247 pairs</div></div>
          <div><MonoLabel style={{ marginBottom: 4 }}>Walkers today</MonoLabel><div style={{ fontFamily: 'Bricolage Grotesque, serif', fontSize: 28, fontWeight: 600, letterSpacing: '-0.03em' }}>1,108</div></div>
        </div>
      </div>
      <div style={{ padding: '20px 28px 8px' }}>
        <PrimaryButton variant="cream" onClick={onRestart}>Run the journey again</PrimaryButton>
      </div>
    </PhoneCanvas>
  );
}

Object.assign(window, {
  LandingScreen, ScanStartScreen, RegisterScreen, CheckpointsScreen,
  ResultsScreen, ShareScreen, DoneScreen, ScannerView,
  LibertyLockup, LibertyMark, PrimaryButton, MonoLabel,
  STATIONS, LEGS_KM, STEPS_PER_KM, computeTotals, legSteps,
  NAVY, NAVY_2, NAVY_3, LIBERTY_BLU, GOLD, CREAM, CREAM_DIM, CREAM_FAINT, LINE, GREEN,
});
