> ## Documentation Index
> Fetch the complete documentation index at: https://developer.uphold.com/llms.txt
> Use this file to discover all available pages before exploring further.

# KYC Widget introduction

> An embeddable UI component for collecting KYC data from your users — fully managed by Uphold, customizable to match your app.

export const KycWidgetDemoMintlify = ({showAnnotation = true, initialPartner = 0, partners = KYC_PARTNER_CONFIGS} = {}) => {
  const [partnerIdx, setPartnerIdx] = useState(initialPartner);
  const [screen, setScreen] = useState("home");
  const [statuses, setStatuses] = useState({
    meridian: "unverified",
    lumen: "unverified",
    vault: "unverified"
  });
  const [animDir, setAnimDir] = useState("fwd");
  const [didNavigate, setDidNavigate] = useState(false);
  const [stepsDone, setStepsDone] = useState({
    1: false,
    2: false,
    3: false
  });
  const cfg = partners[partnerIdx];
  const widgetOpen = screen === "widget";
  const status = statuses[cfg.id];
  useEffect(() => {
    setScreen("home");
    setAnimDir("fwd");
    setStepsDone({
      1: false,
      2: false,
      3: false
    });
  }, [partnerIdx]);
  const go = (s, dir = "fwd") => {
    setDidNavigate(true);
    setAnimDir(dir);
    setScreen(s);
  };
  const onVerify = () => {
    setStepsDone({
      1: true,
      2: false,
      3: false
    });
    go("widget");
  };
  const onComplete = () => {
    setStatuses(st => ({
      ...st,
      [cfg.id]: "pending"
    }));
    setStepsDone({
      1: true,
      2: true,
      3: true
    });
    go("pending");
  };
  const onApprove = () => setStatuses(st => ({
    ...st,
    [cfg.id]: "verified"
  }));
  const onRestart = () => {
    setStatuses(st => ({
      ...st,
      [cfg.id]: "unverified"
    }));
    setStepsDone({
      1: false,
      2: false,
      3: false
    });
    go("home", "back");
  };
  const renderHome = () => {
    if (cfg.id === "meridian") return <MeridianHome status={status} onVerify={onVerify} onApprove={onApprove} onRestart={onRestart} />;
    if (cfg.id === "lumen") return <LumenHome status={status} onVerify={onVerify} onApprove={onApprove} onRestart={onRestart} accent={cfg.accent} />;
    return <VaultHome status={status} onVerify={onVerify} onApprove={onApprove} onRestart={onRestart} />;
  };
  const renderBody = () => {
    if (screen === "home") return renderHome();
    if (screen === "widget") return <KycWidgetFlow flow={cfg.flow} dark={!!cfg.widgetDark} region={cfg.region} theme={cfg.widgetTheme} onBack={() => {
      setStepsDone(s => ({
        ...s,
        2: false
      }));
      go("home", "back");
    }} onComplete={onComplete} />;
    return <PendingScreen partner={cfg.id} onDone={() => go("home", "back")} />;
  };
  const sectionLabel = text => <div className="text-[#0E1525]/45 dark:text-white/45" style={{
    display: "flex",
    alignItems: "center",
    gap: "0.375rem",
    fontSize: "0.6875rem",
    fontWeight: 600,
    letterSpacing: "0.08em",
    textTransform: "uppercase"
  }}>
      {text}
    </div>;
  return <div style={{
    fontFamily: "sans-serif"
  }}>
      <style>{`
        @keyframes kw-fwd { from { opacity: 0; transform: translateX(12px); } to { opacity: 1; transform: translateX(0); } }
        @keyframes kw-back { from { opacity: 0; transform: translateX(-12px); } to { opacity: 1; transform: translateX(0); } }
        @keyframes kw-up { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
        @keyframes kw-pop { 0% { transform: scale(0.6); opacity: 0; } 60% { transform: scale(1.08); opacity: 1; } 100% { transform: scale(1); opacity: 1; } }
        @keyframes kw-pill-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(255,176,32,0); } 50% { box-shadow: 0 0 0 6px rgba(255,176,32,0.6), 0 0 14px rgba(255,176,32,0.4); } }
        @keyframes kw-spin { to { transform: rotate(360deg); } }
        @keyframes kw-flip { 0% { transform: rotateY(0deg); } 100% { transform: rotateY(180deg); } }
        @keyframes kw-toast { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } }
        @keyframes kw-ring {
          0%, 100% { box-shadow: 0 0 0 3px #35B13D, 0 0 28px rgba(53,177,61,0.18), rgba(11,15,30,0.55) 0px 50px 90px -28px, rgba(11,15,30,0.25) 0px 8px 24px -8px; }
          50% { box-shadow: 0 0 0 4px #35B13D, 0 0 64px rgba(53,177,61,0.42), rgba(11,15,30,0.55) 0px 50px 90px -28px, rgba(11,15,30,0.25) 0px 8px 24px -8px; }
        }
        .kw-ring-active { animation: kw-ring 2.4s ease-in-out infinite; }
        .kw-pulse { animation: kw-pill-pulse 2.5s ease-in-out infinite; }
        .kw-spinner { width: 44px; height: 44px; border-radius: 50%; border: 4px solid rgba(53,177,61,0.18); border-top-color: #35B13D; animation: kw-spin 800ms linear infinite; }
        .kw-demo-outer { padding: 2.5rem; display: flex; flex-direction: row; align-items: center; justify-content: center; gap: 1rem; background: radial-gradient(1200px 600px at 50% 0%, rgba(53, 177, 61, 0.1), transparent 60%), linear-gradient(rgb(252, 252, 251), rgb(244, 244, 238)); }
        .dark .kw-demo-outer { background: #0D0F14; }
        .kw-step-num { width: 28px; height: 28px; border-radius: 50%; font-size: 0.8125rem; font-weight: 600; display: flex; align-items: center; justify-content: center; flex-shrink: 0; margin-top: 2px; background: rgba(14,21,37,0.08); color: rgba(14,21,37,0.7); border: none; transition: background 250ms ease, color 250ms ease; }
        .dark .kw-step-num { background: rgba(255,255,255,0.1); color: rgba(255,255,255,0.6); }
        .kw-step-num.is-done, .dark .kw-step-num.is-done { background: #35B13D; color: white; }
        .kw-demo-phone { order: 2; flex: 0 0 auto; display: flex; justify-content: center; position: relative; }
        .kw-demo-panels { display: contents; }
        .kw-demo-left { order: 1; flex: 1; display: flex; flex-direction: column; gap: 1rem; }
        .kw-demo-right { order: 3; flex: 1; display: flex; flex-direction: column; gap: 1.25rem; }
        @media (max-width: 800px) {
          .kw-demo-outer { flex-direction: column; align-items: center; padding: 1.5rem; gap: 0; }
          .kw-demo-left { order: 0; width: 100%; flex: unset; }
          .kw-demo-phone { order: 1; flex: unset; padding-bottom: 48px; }
          .kw-demo-right { order: 2; width: 100%; flex: unset; }
        }
        .kw-partner-btn-selected { background: white; box-shadow: rgba(11, 15, 30, 0.18) 0px 6px 20px -6px; }
        .dark .kw-partner-btn-selected { background: #252A35; box-shadow: none; }
        .kw-caption-muted { color: rgba(14,21,37,0.45); }
        .dark .kw-caption-muted { color: rgba(255,255,255,0.45); }
        .kw-info-card { background: rgba(11, 15, 30, 0.04); border-radius: 0.75rem; padding: 1rem; }
        .dark .kw-info-card { background: #1C1F26; }
      `}</style>

      <div className="dark:bg-[#0D0F14] kw-demo-outer" style={{
    borderRadius: "1.5rem",
    border: "1px solid rgba(0,0,0,0.06)",
    position: "relative"
  }}>

        {}
        <div style={{
    position: "absolute",
    inset: 0,
    borderRadius: "1.5rem",
    background: "rgba(11,15,30,0.5)",
    opacity: widgetOpen ? 1 : 0,
    transition: "opacity 350ms ease",
    pointerEvents: "none",
    zIndex: 1
  }} />

        {}
        <div className="kw-demo-phone" style={{
    paddingTop: showAnnotation ? 48 : 0,
    zIndex: 2
  }}>
          <div style={{
    position: "relative"
  }}>
            <div className={`rounded-[40px] sm:rounded-[44px] ${widgetOpen ? "kw-ring-active" : ""}`} style={{
    transition: "box-shadow 400ms cubic-bezier(.16,1,.3,1)",
    boxShadow: widgetOpen ? undefined : "rgba(11,15,30,0.55) 0px 50px 90px -28px, rgba(11,15,30,0.25) 0px 8px 24px -8px"
  }}>
              <PhoneShell bgClass={cfg.phoneBgClass} lightStatus={!!cfg.lightStatus} borderClass={cfg.lightStatus ? "border-black/10" : "border-white/10"}>
                <div key={screen} className="flex-1 flex flex-col min-h-0" style={{
    animation: !didNavigate ? undefined : animDir === "fwd" ? "kw-fwd 280ms cubic-bezier(.16,1,.3,1)" : "kw-back 280ms cubic-bezier(.16,1,.3,1)"
  }}>
                  {renderBody()}
                </div>
              </PhoneShell>
            </div>

            {showAnnotation && <div style={{
    position: "absolute",
    top: -15,
    left: "50%",
    transform: widgetOpen ? "translateX(-50%) translateY(0)" : "translateX(-50%) translateY(6px)",
    display: "flex",
    alignItems: "center",
    gap: "0.4rem",
    whiteSpace: "nowrap",
    opacity: widgetOpen ? 1 : 0,
    pointerEvents: "none",
    transition: "opacity 300ms ease, transform 300ms cubic-bezier(.16,1,.3,1)",
    zIndex: 5,
    background: "#35B13D",
    color: "#fff",
    padding: "0.34rem 0.78rem",
    borderRadius: "999px",
    fontSize: "0.6875rem",
    fontWeight: 700,
    boxShadow: "0 8px 22px -6px rgba(53,177,61,0.75)"
  }}>
                <LeafLogo color="#ffffff" />
                Uphold KYC Widget
                <span style={{
    opacity: 0.85,
    fontWeight: 600
  }}>· inside {cfg.label}</span>
              </div>}
          </div>
        </div>

        {}
        <div className="kw-demo-panels">

          {}
          <div className="kw-demo-left">
            {sectionLabel("Pick a partner app")}

            <div style={{
    display: "flex",
    flexDirection: "column",
    gap: "4px"
  }}>
              {partners.map((p, i) => <button key={p.id} onClick={() => setPartnerIdx(i)} className={partnerIdx === i ? "kw-partner-btn-selected" : "bg-transparent hover:bg-black/5 dark:hover:bg-white/5"} style={{
    display: "flex",
    alignItems: "center",
    gap: "0.75rem",
    padding: "0.75rem",
    borderRadius: "0.75rem",
    border: "none",
    cursor: "pointer",
    textAlign: "left",
    width: "100%",
    transition: "background 200ms"
  }}>
                  <span style={{
    width: 32,
    height: 32,
    borderRadius: "0.5rem",
    display: "inline-flex",
    alignItems: "center",
    justifyContent: "center",
    fontSize: "0.875rem",
    fontWeight: 800,
    flexShrink: 0,
    background: p.chipBg,
    color: p.chipFg
  }}>{p.label[0]}</span>
                  <div style={{
    flex: 1,
    minWidth: 0
  }}>
                    <div className="text-[#0E1525] dark:text-white" style={{
    fontSize: "0.875rem",
    fontWeight: 700,
    lineHeight: 1.3
  }}>{p.label}</div>
                    <div className="text-[#0E1525]/50 dark:text-white/50" style={{
    fontSize: "0.75rem",
    marginTop: 2,
    lineHeight: 1.3
  }}>{p.tag} · {p.desc}</div>
                  </div>
                  {partnerIdx === i && <svg width="18" height="18" viewBox="0 0 24 24" fill="none" style={{
    flexShrink: 0
  }}>
                      <circle cx="12" cy="12" r="11" fill="#35B13D" />
                      <path d="M7 12l3.5 3.5L17 8" stroke="white" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" />
                    </svg>}
                </button>)}
            </div>

            <div className="kw-info-card">
              <div className="text-[#0E1525]/45 dark:text-white/45" style={{
    fontSize: "0.6875rem",
    fontWeight: 600,
    letterSpacing: "0.08em",
    textTransform: "uppercase",
    marginBottom: "0.55rem"
  }}>What this demonstrates</div>
              <div style={{
    display: "flex",
    alignItems: "center",
    gap: "0.5rem",
    marginBottom: "0.375rem"
  }}>
                <CountryFlag region={cfg.region} />
                <div className="text-[#0E1525] dark:text-white" style={{
    fontSize: "0.875rem",
    fontWeight: 700
  }}>{cfg.scenario.headline} · {cfg.regionLabel}</div>
              </div>
              <div className="text-[#0E1525]/55 dark:text-white/55" style={{
    fontSize: "0.8125rem",
    lineHeight: 1.5
  }}>{cfg.scenario.detail}</div>
            </div>
          </div>

          {}
          <div className="kw-demo-right">
            {sectionLabel("Try the flow")}
            {[{
    n: 1,
    title: `Tap "${cfg.cta}"`,
    desc: "The partner host's UI and UX. Yours stays yours."
  }, {
    n: 2,
    title: "Widget takes over the body",
    desc: ({
      "all": "Uphold collects personal details and address, then runs an identity check — address verified automatically.",
      "identity-poa": "Uphold runs an identity check; the address is verified automatically from the ID.",
      "proof-of-address": "Uphold collects a proof-of-address document only."
    })[cfg.flow] + " Only what you configure."
  }, {
    n: 3,
    title: "Submit, return",
    desc: "KYC Widget emits complete event, the user lands back on your app — pending review."
  }].map(step => <div key={step.n} style={{
    display: "flex",
    gap: "0.75rem"
  }}>
                <div className={`kw-step-num${stepsDone[step.n] ? " is-done" : ""}`}>{step.n}</div>
                <div>
                  <div className="text-[#0E1525] dark:text-white" style={{
    fontSize: "0.875rem",
    fontWeight: 700,
    lineHeight: 1.3
  }}>{step.title}</div>
                  <div className="text-[#0E1525]/55 dark:text-white/55" style={{
    fontSize: "0.8125rem",
    marginTop: 4,
    lineHeight: 1.5
  }}>{step.desc}</div>
                </div>
              </div>)}

            <div className="kw-info-card">
              <div className="text-[#0E1525] dark:text-white" style={{
    fontSize: "0.875rem",
    fontWeight: 700,
    marginBottom: "0.375rem"
  }}>Approval is asynchronous</div>
              <div className="text-[#0E1525]/55 dark:text-white/55" style={{
    fontSize: "0.8125rem",
    lineHeight: 1.5
  }}>The <code>complete</code> event only means "submitted". The approve/reject outcome arrives later via webhooks — tap <em>Simulate webhook</em> on the home screen to see the account unlock.</div>
            </div>
          </div>

        </div>

      </div>
    </div>;
};

export const KYC_PARTNER_CONFIGS = [{
  id: "meridian",
  label: "Meridian",
  tag: "Investing",
  desc: "ETF & equities",
  chipBg: "#1d2738",
  chipFg: "#fff",
  phoneBgClass: "bg-[#FAFAF7]",
  accent: "#1d2738",
  region: "GB",
  regionLabel: "UK",
  lightStatus: true,
  flow: "identity-poa",
  cta: "Verify your identity",
  processes: ["identity", "proof-of-address"],
  scenario: {
    headline: "Unlock trading",
    detail: "A light-theme Widget collects identity and proof of address (verified automatically) so the user can unlock full access and trade."
  }
}, {
  id: "lumen",
  label: "Lumen",
  tag: "Crypto",
  desc: "Crypto & staking",
  chipBg: "#0B0D10",
  chipFg: "#E8FF3A",
  phoneBgClass: "bg-[#0B0D10]",
  accent: "#E8FF3A",
  region: "US",
  regionLabel: "US",
  lightStatus: false,
  widgetDark: true,
  flow: "proof-of-address",
  cta: "Unlock",
  processes: ["proof-of-address"],
  scenario: {
    headline: "Proof of address only",
    detail: "A dark-theme Widget matching the app collects a proof-of-address document on its own — used when the address can't be verified automatically from an ID."
  }
}, {
  id: "vault",
  label: "Vault",
  tag: "Neobank",
  desc: "Spending & savings",
  chipBg: "#FF5C39",
  chipFg: "#fff",
  phoneBgClass: "bg-[#F4EFE8]",
  accent: "#FF5C39",
  region: "EU",
  regionLabel: "EU",
  lightStatus: true,
  flow: "all",
  cta: "Start verification",
  processes: ["identity", "proof-of-address"],
  widgetTheme: {
    bg: "#F4EFE8",
    fg: "#1A1410",
    ctaBg: "#FF5C39",
    ctaFg: "#ffffff"
  },
  scenario: {
    headline: "Themed account setup",
    detail: "The Widget is themed to match Vault's colors and runs the full flow — profile, address, identity and proof of address — to set up the account before using the app."
  }
}];

export const PendingScreen = ({partner, onDone}) => {
  const isDark = partner === "lumen";
  const isVault = partner === "vault";
  const bgStyle = isDark ? {
    backgroundColor: "#0B0D10",
    color: "white"
  } : isVault ? {
    backgroundColor: "#F4EFE8",
    color: "#1A1410"
  } : {
    backgroundColor: "#FAFAF7",
    color: "#0E1525"
  };
  const accent = isDark ? "#E8FF3A" : isVault ? "#FF5C39" : "#1d2738";
  const muted = isDark ? "text-white/60" : "text-[#0E1525]/60";
  return <div className="flex-1 flex flex-col" style={{
    ...bgStyle,
    animation: "kw-up 320ms cubic-bezier(.16,1,.3,1)"
  }}>
      <div className="flex-1 flex flex-col items-center justify-center px-8 text-center">
        <div className={`w-20 h-20 rounded-full flex items-center justify-center mb-6 text-[#35B13D] ${isDark ? "bg-white/[0.07]" : "bg-black/[0.05]"}`} style={{
    animation: "kw-pop 500ms cubic-bezier(.16,1,.3,1) both"
  }}>
          <IcoCheck />
        </div>
        <div className="text-[24px] font-extrabold tracking-tight mb-2">Verification submitted</div>
        <div className={`text-[14px] leading-relaxed ${muted}`}>Thanks — we've received your details. We're reviewing them now and we'll let you know the outcome shortly.</div>
        <div className={`mt-5 flex items-center gap-2 text-[12px] font-semibold ${muted}`}>
          <span className="w-1.5 h-1.5 rounded-full inline-block" style={{
    background: "#35B13D"
  }} />
          Outcome delivered to your backend via webhook
        </div>
      </div>
      <div className="px-5 pt-4 pb-10 flex-shrink-0">
        <button onClick={onDone} className="w-full border-0 rounded-full text-[15px] font-bold cursor-pointer" style={{
    height: "3rem",
    padding: 0,
    background: isDark ? accent : isVault ? "#1A1410" : "#0E1525",
    color: isDark ? "#0B0D10" : "#fff"
  }}>
          Back to {partner === "meridian" ? "Meridian" : partner === "lumen" ? "Lumen" : "Vault"}
        </button>
      </div>
    </div>;
};

export const VaultDashboard = ({onRestart}) => {
  const actions = [["Add money", "M12 5v14M5 12h14", true], ["Send", "M12 19V5M5 12l7-7 7 7", false], ["Pots", "M4 7h16v4a4 4 0 0 1-4 4H8a4 4 0 0 1-4-4zM4 7l1.5-3h13L20 7M9 15v2a3 3 0 0 0 6 0v-2", false]];
  return <div className="flex-1 flex flex-col min-h-0 bg-[#F4EFE8] text-[#1A1410] relative">
      <div className="flex items-center justify-between px-5 pt-4 pb-2">
        <div className="flex items-center gap-2">
          <svg className="w-[22px] h-[22px]" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="10" stroke="#1A1410" strokeWidth="2" /><path d="M9 12L12 15 17 9" stroke="#FF5C39" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" fill="none" /></svg>
          <span className="text-[15px] font-bold">Vault</span>
        </div>
        <div className="flex items-center gap-2">
          <span className="text-[11px] font-bold uppercase tracking-[0.8px] px-2.5 py-0.5 rounded-full bg-[#FF5C39] text-white">Pro</span>
          <div className="w-9 h-9 rounded-full bg-[#1A1410] text-white flex items-center justify-center text-xs font-extrabold">JS</div>
        </div>
      </div>
      <div className="px-5 pt-5">
        <div className="text-[13px] font-semibold text-[#1A1410]/60">Spending account</div>
        <div className="text-[42px] font-extrabold tracking-tight mt-2 tabular-nums">€3,182.40</div>
      </div>
      <div className="grid grid-cols-3 gap-2 px-5 pt-5">
        {actions.map(([l, d, primary]) => <div key={l} className={`px-2 py-3 rounded-2xl text-[13px] font-bold flex flex-col items-center gap-1.5 ${primary ? "bg-[#FF5C39] text-white" : "bg-[#1A1410]/5 text-[#1A1410]"}`}>
            <svg className="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d={d} /></svg>
            <span>{l}</span>
          </div>)}
      </div>
      <div className="px-5 pt-5">
        <div className="text-sm font-bold mb-2.5">Saving pots</div>
        <div className="flex gap-2">
          {[["✈", "Travel", "€842", "#FFE8DA"], ["₣", "Tax", "€1,200", "#E8E2FF"], ["◓", "Roof", "€3,400", "#DCEEDC"]].map(([e, l, a, t]) => <div key={l} className="flex-1 rounded-2xl p-3" style={{
    background: t
  }}>
              <div className="text-[20px] mb-1">{e}</div>
              <div className="text-xs font-bold text-[#1A1410]/70">{l}</div>
              <div className="text-[15px] font-bold mt-0.5 tabular-nums">{a}</div>
            </div>)}
        </div>
      </div>
      <div className="px-5 pt-5 flex-1">
        <div className="text-sm font-bold mb-2">Today</div>
        {[["P", "Pret a Manger", "Coffee", "-€4.85", false], ["U", "Uber", "Transport", "-€12.40", false], ["A", "Acme Co", "Salary", "+€2,840.00", true]].map(([i, n, c, a, pos]) => <div key={n} className="flex items-center gap-3 py-2.5 border-b border-[#1A1410]/5">
            <div className="w-9 h-9 rounded-full bg-[#1A1410]/10 flex items-center justify-center text-sm font-bold flex-shrink-0">{i}</div>
            <div className="flex-1">
              <div className="text-sm font-bold">{n}</div>
              <div className="text-xs text-[#1A1410]/50 mt-px">{c}</div>
            </div>
            <div className={`text-sm font-bold tabular-nums ${pos ? "text-[#0E8C5C]" : "text-[#1A1410]"}`}>{a}</div>
          </div>)}
      </div>
      <div className="flex justify-around px-5 pt-3 pb-2.5 border-t border-[#1A1410]/5 flex-shrink-0">
        {[["Home", "M3 12l9-9 9 9M5 10v10h14V10", true], ["Cards", "M3 7h18v10H3zM3 11h18"], ["Invest", "M3 18h4V8H3zM10 18h4V4h-4zM17 18h4v-7h-4z"], ["More", "M5 12h.01M12 12h.01M19 12h.01"]].map(([l, d, a]) => <NavTab key={l} label={l} d={d} active={a} accent="#FF5C39" />)}
      </div>

      {}
      <div className="absolute left-3 right-3 bottom-[74px] z-30 flex items-center gap-3 px-3.5 py-3 rounded-2xl bg-white" style={{
    boxShadow: "0 12px 30px -8px rgba(26,20,16,0.4)",
    animation: "kw-toast 380ms cubic-bezier(.16,1,.3,1)"
  }}>
        <div className="w-8 h-8 rounded-full bg-[#35B13D] text-white flex items-center justify-center flex-shrink-0"><IcoCheckSm /></div>
        <div className="flex-1 min-w-0">
          <div className="text-[13px] font-bold text-[#1A1410]">Profile verified</div>
          <div className="text-[11.5px] text-[#1A1410]/55 leading-snug">Your Vault account is now active.</div>
        </div>
        <button onClick={onRestart} className="flex-shrink-0 px-3 py-1.5 rounded-lg text-[12px] font-bold text-white border-0 cursor-pointer bg-[#FF5C39]">Start over</button>
      </div>
    </div>;
};

export const VaultHome = ({status, onVerify, onApprove, onRestart}) => {
  if (status === "verified") return <VaultDashboard onRestart={onRestart} />;
  const steps = [{
    t: "Create your account",
    s: "done"
  }, {
    t: "Add your phone number",
    s: "done"
  }, {
    t: "Profile verification",
    s: status === "verified" ? "done" : "active",
    gate: true
  }];
  const doneCount = steps.filter(x => x.s === "done").length;
  const cardShadow = {
    boxShadow: "0 6px 20px -8px rgba(26,20,16,0.22)"
  };
  return <div className="flex-1 flex flex-col min-h-0 bg-[#F4EFE8] text-[#1A1410]">
      <div className="flex items-center justify-between px-5 pt-4 pb-2">
        <div className="flex items-center gap-2">
          <svg className="w-[22px] h-[22px]" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="10" stroke="#1A1410" strokeWidth="2" /><path d="M9 12L12 15 17 9" stroke="#FF5C39" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" fill="none" /></svg>
          <span className="text-[15px] font-bold">Vault</span>
        </div>
        <div className="w-9 h-9 rounded-full bg-[#1A1410] text-white flex items-center justify-center text-xs font-extrabold">JS</div>
      </div>
      <div className="px-5 pt-3 pb-1">
        <div className="text-[22px] font-extrabold tracking-tight">Finish setting up</div>
        <div className="text-[13px] text-[#1A1410]/55 mt-1.5">{doneCount} of {steps.length} steps complete</div>
        <div className="mt-3 h-1.5 rounded-full bg-[#1A1410]/8 overflow-hidden">
          <div className="h-full rounded-full bg-[#FF5C39] transition-all duration-500" style={{
    width: `${doneCount / steps.length * 100}%`
  }} />
        </div>
      </div>
      <div className="px-5 pt-5 flex-1">
        {steps.map((s, i) => {
    const isLast = i === steps.length - 1;
    const isActive = s.s === "active";
    const isDone = s.s === "done";
    return <div key={i} className="flex gap-3.5">
              {}
              <div className="flex flex-col items-center flex-shrink-0">
                <div className="w-7 h-7 rounded-full flex items-center justify-center text-white" style={{
      background: isDone ? "#35B13D" : isActive ? "#FF5C39" : "rgba(26,20,16,0.08)",
      color: isDone || isActive ? "#fff" : "rgba(26,20,16,0.4)"
    }}>
                  {isDone ? <IcoCheckSm /> : <span className="text-[12px] font-bold">{i + 1}</span>}
                </div>
                {!isLast && <div className="w-[2px] flex-1 my-1.5 rounded-full" style={{
      background: isDone ? "#35B13D" : "rgba(26,20,16,0.12)"
    }} />}
              </div>
              {}
              <div className={`flex-1 min-w-0 ${isLast ? "pb-1" : "pb-5"}`}>
                {isActive && s.gate ? status === "pending" ? <div className="rounded-2xl bg-white p-4" style={cardShadow}>
                      <div className="flex items-center gap-2 mb-1">
                        <span className="text-[#FF5C39]"><IcoClock /></span>
                        <span className="text-[15px] font-bold">Verification in review</span>
                      </div>
                      <div className="text-[12.5px] text-[#1A1410]/55 leading-snug mb-3">We're checking your details. This usually takes a few minutes.</div>
                      <button onClick={onApprove} className="w-full flex items-center justify-center gap-1.5 py-2 rounded-xl text-[12px] font-bold border border-dashed border-[#1A1410]/15 text-[#1A1410]/55 bg-transparent cursor-pointer">
                        Simulate webhook <IcoArrow /> approved
                      </button>
                    </div> : <div className="rounded-2xl bg-white p-4 border border-[#FF5C39]/25" style={cardShadow}>
                      <div className="text-[15px] font-bold mb-1">Profile verification</div>
                      <div className="text-[12.5px] text-[#1A1410]/55 leading-snug mb-3.5">We need to confirm who you are before we can open your account.</div>
                      <button onClick={onVerify} className="kw-pulse w-full py-2.5 rounded-xl text-[13px] font-bold cursor-pointer border-0 bg-[#FF5C39] text-white">Start verification</button>
                    </div> : <div className="pt-0.5">
                    <div className={`text-[14px] font-semibold ${isDone ? "text-[#1A1410]/45" : "text-[#1A1410]"}`}>{s.t}</div>
                    {isDone && <div className="text-[12px] text-[#1A1410]/40 mt-px">Completed</div>}
                  </div>}
              </div>
            </div>;
  })}
        {status === "verified" && <div className="mt-1 flex items-center gap-2.5 px-3.5 py-3 rounded-2xl bg-[#35B13D]/10">
            <div className="w-8 h-8 rounded-full bg-[#35B13D] text-white flex items-center justify-center flex-shrink-0"><IcoCheckSm /></div>
            <div className="text-[13px] font-semibold">All set — your Vault card is on its way.</div>
          </div>}
      </div>
      <div className="flex justify-around px-5 pt-3 pb-2.5 border-t border-[#1A1410]/5 flex-shrink-0">
        {[["Home", "M3 12l9-9 9 9M5 10v10h14V10", true], ["Cards", "M3 7h18v10H3zM3 11h18"], ["Invest", "M3 18h4V8H3zM10 18h4V4h-4zM17 18h4v-7h-4z"], ["More", "M5 12h.01M12 12h.01M19 12h.01"]].map(([l, d, a]) => <NavTab key={l} label={l} d={d} active={a} accent="#FF5C39" />)}
      </div>
    </div>;
};

export const LumenHome = ({status, onVerify, onApprove, onRestart, accent = "#E8FF3A"}) => {
  const verified = status === "verified";
  const assets = [{
    g: "₿",
    c: "#F7931A",
    n: "Bitcoin",
    sym: "BTC",
    price: "$95,240",
    amt: "0.1842 BTC",
    v: "$8,924",
    ch: "+2.1%",
    up: true
  }, {
    g: "Ξ",
    c: "#627EEA",
    n: "Ethereum",
    sym: "ETH",
    price: "$3,180",
    amt: "1.214 ETH",
    v: "$2,816",
    ch: "+0.8%",
    up: true
  }, {
    g: "◎",
    c: "#9945FF",
    n: "Solana",
    sym: "SOL",
    price: "$176.20",
    amt: "6.50 SOL",
    v: "$1,145",
    ch: "-1.4%",
    up: false
  }];
  return <div className="flex-1 flex flex-col min-h-0 bg-[#0B0D10] text-white">
      <LumenBanner status={status} accent={accent} onVerify={onVerify} onApprove={onApprove} onRestart={onRestart} />
      <div className="flex items-center justify-between px-5 pt-4 pb-2">
        <div className="flex items-center gap-2">
          <div className="w-8 h-8 rounded-[10px] flex items-center justify-center" style={{
    background: accent
  }}>
            <svg className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="#0B0D10" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2 L4 12 L12 16 L20 12 Z" /><path d="M4 12 L12 22 L20 12" /></svg>
          </div>
          <span className="text-[15px] font-bold">Lumen</span>
        </div>
        <div className="w-9 h-9 rounded-full bg-gradient-to-br from-[#7c5cff] to-[#ff5cae] flex items-center justify-center text-xs font-bold">JS</div>
      </div>
      <div className="px-5 pt-4">
        <div className="text-xs uppercase tracking-[1.2px] text-white/40 font-semibold">Portfolio value</div>
        <div className="text-[36px] font-extrabold tracking-tight mt-1 tabular-nums">{verified ? "$12,847.62" : "$0.00"}</div>
        {!verified && <div className="text-[13px] text-white/45 mt-1">Verify your address to start trading.</div>}
      </div>
      <div className="px-5 pt-6 flex-1">
        <div className="text-[15px] font-bold mb-2.5">{verified ? "Holdings" : "Markets"}</div>
        {assets.map(h => <div key={h.n} className="flex items-center gap-3 py-2.5 border-b border-white/5">
            <div className="w-9 h-9 rounded-full text-white flex items-center justify-center text-sm font-bold flex-shrink-0" style={{
    background: h.c
  }}>{h.g}</div>
            <div className="flex-1"><div className="text-sm font-bold">{h.n}</div><div className="text-xs text-white/50 mt-px">{verified ? h.amt : h.sym}</div></div>
            <div className="text-right"><div className="text-sm font-bold tabular-nums">{verified ? h.v : h.price}</div><div className={`text-xs mt-px ${h.up ? "text-[#5EE38F]" : "text-[#FF6B6B]"}`}>{h.ch}</div></div>
          </div>)}
      </div>
      <div className="flex justify-around px-5 pt-3 pb-2.5 border-t border-white/5 flex-shrink-0">
        {[["Home", "M3 12l9-9 9 9M5 10v10h14V10", true], ["Markets", "M3 18h4V8H3zM10 18h4V4h-4zM17 18h4v-7h-4z"], ["Earn", "M12 2v20M5 9l7-7 7 7M5 15l7 7 7-7"], ["Profile", "M12 12a4 4 0 100-8 4 4 0 000 8zM4 22a8 8 0 0116 0"]].map(([l, d, a]) => <NavTab key={l} label={l} d={d} active={a} dark />)}
      </div>
    </div>;
};

export const LumenBanner = ({status, accent, onVerify, onApprove, onRestart}) => {
  if (status === "verified") {
    return <div className="flex items-center gap-3 px-5 py-2.5 flex-shrink-0" style={{
      background: "rgba(53,177,61,0.14)",
      borderBottom: "1px solid rgba(53,177,61,0.25)"
    }}>
        <div className="w-9 h-9 rounded-full flex items-center justify-center flex-shrink-0 bg-[#35B13D] text-white"><IcoCheckSm /></div>
        <div className="flex-1 min-w-0">
          <div className="text-[13px] font-bold text-white">Address verified</div>
          <div className="text-[11.5px] text-white/55 mt-px leading-snug">Full access unlocked.</div>
        </div>
        {onRestart && <button onClick={onRestart} className="flex-shrink-0 px-3 py-1.5 rounded-lg text-[12px] font-bold cursor-pointer border-0" style={{
      background: accent,
      color: "#0B0D10"
    }}>Start over</button>}
      </div>;
  }
  if (status === "pending") {
    return <div className="flex items-center gap-3 px-5 py-2.5 flex-shrink-0" style={{
      background: "rgba(255,255,255,0.06)",
      borderBottom: "1px solid rgba(255,255,255,0.08)"
    }}>
        <div className="w-9 h-9 rounded-full flex items-center justify-center flex-shrink-0 bg-white/10 text-white/70"><IcoClock /></div>
        <div className="flex-1 min-w-0">
          <div className="text-[13px] font-bold text-white">Verification in review</div>
          <div className="text-[11.5px] text-white/50 mt-px leading-snug">We're checking your details.</div>
        </div>
        <button onClick={onApprove} className="flex-shrink-0 flex items-center gap-1 px-2.5 py-1.5 rounded-lg text-[11px] font-bold cursor-pointer bg-transparent border border-dashed border-white/20 text-white/55">
          webhook <IcoArrow />
        </button>
      </div>;
  }
  return <div className="flex items-center gap-3 px-5 py-2.5 flex-shrink-0" style={{
    background: "rgba(232,255,58,0.12)",
    borderBottom: "1px solid rgba(232,255,58,0.22)"
  }}>
      <div className="w-9 h-9 rounded-full flex items-center justify-center flex-shrink-0" style={{
    background: "rgba(232,255,58,0.18)",
    color: accent
  }}><IcoLock /></div>
      <div className="flex-1 min-w-0">
        <div className="text-[13px] font-bold text-white">Limited mode</div>
        <div className="text-[11.5px] text-white/55 mt-px leading-snug">Verify your address to unlock full access.</div>
      </div>
      <button onClick={onVerify} className="kw-pulse flex-shrink-0 px-3.5 py-2 rounded-xl text-[12px] font-bold cursor-pointer border-0" style={{
    background: accent,
    color: "#0B0D10"
  }}>Unlock</button>
    </div>;
};

export const MeridianHome = ({status, onVerify, onApprove, onRestart}) => <div className="flex-1 flex flex-col min-h-0 bg-[#FAFAF7] text-[#0E1525]">
    <div className="flex items-center justify-between px-5 pt-4 pb-2">
      <div className="flex items-center gap-2">
        <svg className="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="#1d2738" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 18L9 10l4 4 8-10" /><circle cx="9" cy="10" r="1.4" fill="#1d2738" stroke="none" /><circle cx="13" cy="14" r="1.4" fill="#1d2738" stroke="none" /></svg>
        <span className="text-[15px] font-bold">Meridian</span>
      </div>
      <div className="w-9 h-9 rounded-full bg-[#1d2738] flex items-center justify-center text-xs font-extrabold text-white">JS</div>
    </div>
    <div className="px-5 pt-3 pb-1"><div className="text-[22px] font-extrabold tracking-tight">Welcome, John</div></div>
    <GateCard status={status} accent="#1d2738" onVerify={onVerify} onApprove={onApprove} onRestart={onRestart} labels={{
  title: "Verify to start investing",
  subtitle: "UK regulations require us to confirm your identity before you can fund your account and trade.",
  cta: "Verify your identity",
  verifiedSub: "Your account is fully active. Start investing."
}} />
    <div className="px-5 pt-5 flex-1">
      <div className="flex justify-between items-center mb-3">
        <span className="text-[15px] font-bold">Portfolio</span>
        {status !== "verified" && <span className="flex items-center gap-1 text-xs text-[#0E1525]/45"><IcoLock /> Locked</span>}
      </div>
      <div className={status === "verified" ? "" : "opacity-40 pointer-events-none select-none"} style={status === "verified" ? undefined : {
  filter: "blur(1.5px)"
}}>
        {[{
  l: "V",
  c: "#1A1F71",
  n: "VWRP",
  s: "Vanguard FTSE All-World",
  v: "£8,402",
  ch: "+1.4%"
}, {
  l: "A",
  c: "#0071E3",
  n: "AAPL",
  s: "Apple Inc.",
  v: "£4,128",
  ch: "+0.6%"
}, {
  l: "₿",
  c: "#F7931A",
  n: "BTC",
  s: "Bitcoin",
  v: "£5,756",
  ch: "+2.1%"
}].map(p => <div key={p.n} className="flex items-center gap-3 py-2.5 border-b border-[#0E1525]/5">
            <div className="w-9 h-9 rounded-full text-white flex items-center justify-center text-[13px] font-extrabold flex-shrink-0" style={{
  background: p.c
}}>{p.l}</div>
            <div className="flex-1"><div className="text-sm font-bold">{p.n}</div><div className="text-xs text-[#0E1525]/50 mt-px">{p.s}</div></div>
            <div className="text-right"><div className="text-sm font-bold tabular-nums">{p.v}</div><div className="text-xs mt-px text-[#0E8C5C]">{p.ch}</div></div>
          </div>)}
      </div>
    </div>
    <div className="flex justify-around px-5 pt-3 pb-2.5 border-t border-[#0E1525]/5 flex-shrink-0">
      {[["Home", "M3 12l9-9 9 9M5 10v10h14V10", true], ["Invest", "M3 18h4V8H3zM10 18h4V4h-4zM17 18h4v-7h-4z"], ["Plans", "M9 12h6M9 16h3M7 4h10a2 2 0 012 2v14l-3-2-2 2-2-2-2 2-2-2-3 2V6a2 2 0 012-2z"], ["You", "M12 12a4 4 0 100-8 4 4 0 000 8zM4 22a8 8 0 0116 0"]].map(([l, d, a]) => <NavTab key={l} label={l} d={d} active={a} accent="#1d2738" />)}
    </div>
  </div>;

export const GateCard = ({status, accent, fg = "#fff", labels, onVerify, onApprove, onRestart, dark}) => {
  if (status === "verified") {
    return <div className={`mx-5 mt-2 p-4 rounded-3xl flex items-center gap-3.5 ${dark ? "bg-white/[0.05]" : "bg-[#35B13D]/10"}`}>
        <div className="w-11 h-11 rounded-full flex items-center justify-center flex-shrink-0 bg-[#35B13D] text-white"><IcoCheck /></div>
        <div className="flex-1 min-w-0">
          <div className={`text-[15px] font-bold ${dark ? "text-white" : "text-[#0E1525]"}`}>Identity verified</div>
          <div className={`text-[12.5px] mt-px ${dark ? "text-white/55" : "text-[#0E1525]/55"}`}>{labels.verifiedSub}</div>
        </div>
        {onRestart && <button onClick={onRestart} className="flex-shrink-0 px-3 py-1.5 rounded-lg text-[12px] font-bold cursor-pointer border-0" style={{
      background: accent,
      color: fg
    }}>Start over</button>}
      </div>;
  }
  if (status === "pending") {
    return <div className={`mx-5 mt-2 p-5 rounded-3xl ${dark ? "bg-white/[0.05]" : "bg-black/[0.04]"}`}>
        <div className="flex items-center gap-3.5">
          <div className={`w-11 h-11 rounded-full flex items-center justify-center flex-shrink-0 ${dark ? "bg-white/10 text-white" : "bg-[#0E1525]/8 text-[#0E1525]"}`}><IcoClock /></div>
          <div className="flex-1">
            <div className={`text-[15px] font-bold ${dark ? "text-white" : "text-[#0E1525]"}`}>Verification in review</div>
            <div className={`text-[12.5px] mt-px ${dark ? "text-white/55" : "text-[#0E1525]/55"}`}>We're checking your details. This usually takes a few minutes.</div>
          </div>
        </div>
        <button onClick={onApprove} className={`mt-3.5 w-full flex items-center justify-center gap-1.5 py-2 rounded-xl text-[12px] font-bold border border-dashed cursor-pointer bg-transparent ${dark ? "border-white/20 text-white/60" : "border-black/15 text-[#0E1525]/55"}`}>
          Simulate webhook <IcoArrow /> approved
        </button>
      </div>;
  }
  return <div className="mx-5 mt-2 p-5 rounded-3xl relative overflow-hidden" style={{
    background: accent,
    color: fg
  }}>
      <div className="absolute -right-10 -bottom-7 w-40 h-40 rounded-full bg-white/5 pointer-events-none" />
      <div className="flex items-center gap-3 mb-2.5">
        <div className="w-10 h-10 rounded-xl bg-white/15 flex items-center justify-center flex-shrink-0"><IcoShield /></div>
        <div className="text-[18px] font-extrabold tracking-tight leading-tight">{labels.title}</div>
      </div>
      <div className="text-[13px] opacity-80 mb-4 leading-snug">{labels.subtitle}</div>
      <button onClick={onVerify} className="kw-pulse w-full py-2.5 border-0 rounded-xl bg-white text-[14px] font-bold cursor-pointer flex items-center justify-center gap-2" style={{
    color: "#0E1525"
  }}>
        <IcoLock /> {labels.cta}
      </button>
    </div>;
};

export const KycWidgetFlow = ({flow = "all", dark = false, region = "GB", theme, onBack, onComplete}) => {
  const formSteps = FLOW_STEPS[flow] || FLOW_STEPS["identity-poa"];
  const [screen, setScreen] = useState(flow === "all" ? "welcome" : formSteps[0]);
  const [docType, setDocType] = useState("passport");
  const [poaType, setPoaType] = useState(null);
  const [poaFile, setPoaFile] = useState(false);
  const [captureStep, setCaptureStep] = useState("front");
  const [selfieShot, setSelfieShot] = useState(false);
  const bg = theme ? {
    backgroundColor: theme.bg,
    color: theme.fg
  } : dark ? {
    backgroundColor: "#0E1116",
    color: "white"
  } : {
    backgroundColor: "#f4f4f5",
    color: "#0E1525"
  };
  const muted = dark ? "text-white/55" : "text-[#0E1525]/55";
  const ctaBg = theme && theme.ctaBg;
  const ctaFg = theme && theme.ctaFg;
  const country = region === "US" ? "United States" : region === "EU" ? "Germany" : "United Kingdom";
  const stepIndex = s => formSteps.indexOf(s);
  const total = formSteps.length;
  const next = from => {
    const i = formSteps.indexOf(from);
    if (i === -1 || i === formSteps.length - 1) setScreen("submitting"); else setScreen(formSteps[i + 1]);
  };
  const back = from => {
    const i = formSteps.indexOf(from);
    if (i <= 0) setScreen("welcome"); else setScreen(formSteps[i - 1]);
  };
  useEffect(() => {
    if (screen !== "submitting") return;
    const t = setTimeout(() => onComplete && onComplete(), 1300);
    return () => clearTimeout(t);
  }, [screen]);
  if (screen === "welcome") {
    const ready = ["Full name and date of birth", "Citizenship and address", "Valid ID (driver's license, state ID card or passport) and a selfie"];
    return <div className="flex-1 flex flex-col min-h-0" style={bg}>
        <div className="px-5 pt-4 pb-2 flex-shrink-0">
          <button onClick={onBack} className={`w-10 h-10 rounded-full border-0 flex items-center justify-center cursor-pointer ${dark ? "bg-white/10 text-white" : "bg-black/5 text-[#0E1525]"}`}><IcoClose /></button>
        </div>
        <div className="flex-1 px-5 overflow-y-auto overflow-x-hidden">
          <div className="flex justify-center mb-1"><IllustrationIdDocs /></div>
          <h1 className="m-0 mt-2 mb-2 text-[28px] font-bold tracking-tight text-center" style={{
      color: dark ? "#ffffff" : "#0E1525"
    }}>Personal details</h1>
          <div className={`text-[15px] leading-snug mb-6 text-center ${muted}`}>A few details are needed to set up the account.</div>
          <div className={`rounded-2xl p-5 ${dark ? "bg-white/[0.04]" : "bg-white"}`}>
            <div className="text-[15px] font-bold mb-4">Have these ready</div>
            <div className="flex flex-col gap-4">
              {ready.map((t, i) => <div key={i} className="flex items-start gap-3.5">
                  <span className={`flex-shrink-0 ${dark ? "text-white" : "text-[#0E1525]"}`}><IcoCheckCircle /></span>
                  <span className="text-[14px] leading-snug">{t}</span>
                </div>)}
            </div>
          </div>
        </div>
        <div className="px-5 pt-4 pb-3 flex-shrink-0"><WBtn onClick={() => setScreen(formSteps[0])} dark={dark} bg={ctaBg} fg={ctaFg}>Get started</WBtn></div>
        <WFooter dark={dark} />
      </div>;
  }
  if (screen === "verify-intro") {
    const hasIdentity = formSteps.includes("identity");
    const linkColor = dark ? "text-white" : "text-[#0E1525]";
    return <div className="flex-1 flex flex-col min-h-0" style={bg}>
        <div className="px-5 pt-4 pb-2 flex-shrink-0">
          <button onClick={onBack} className={`w-10 h-10 rounded-full border-0 flex items-center justify-center cursor-pointer ${dark ? "bg-white/10 text-white" : "bg-black/5 text-[#0E1525]"}`}><IcoClose /></button>
        </div>
        <div className="flex-1 px-5 overflow-y-auto overflow-x-hidden">
          <div className="flex justify-center mt-3 mb-1"><IllustrationChecklist /></div>
          <h1 className="m-0 mt-2 mb-2 text-[28px] font-bold tracking-tight text-center" style={{
      color: dark ? "#ffffff" : "#0E1525"
    }}>{hasIdentity ? "Profile verification" : "Address verification"}</h1>
          <div className={`text-[15px] leading-snug mb-6 text-center ${muted}`}>Complete these steps to unlock full access.</div>
          <div className={`rounded-2xl p-5 ${dark ? "bg-white/[0.04]" : "bg-white"}`}>
            {hasIdentity && <>
                <div>
                  <div className="flex items-center justify-between gap-3">
                    <span className="text-[15px] font-bold">Identity check</span>
                    <span className={`flex items-center gap-2 text-[14px] ${dark ? "text-white/80" : "text-[#0E1525]/80"}`}>1 min <ClockBadge /></span>
                  </div>
                  <div className={`text-[13px] leading-snug mt-1.5 ${muted}`}>Choose an ID that includes an address for automatic verification. <span className={`font-bold ${linkColor}`}>Learn more</span></div>
                </div>
                <div className="h-px my-4" style={{
      background: dark ? "rgba(255,255,255,0.08)" : "rgba(14,21,37,0.08)"
    }} />
              </>}
            <div className="flex items-center justify-between gap-3">
              <span className="text-[15px] font-bold">Address check</span>
              <span className={`flex items-center gap-2 text-[14px] ${dark ? "text-white/80" : "text-[#0E1525]/80"}`}>
                {hasIdentity ? <>Automatic <AutoBadge /></> : <>1 min <ClockBadge /></>}
              </span>
            </div>
          </div>
        </div>
        <div className="px-5 pt-4 pb-3 flex-shrink-0"><WBtn onClick={() => next("verify-intro")} dark={dark} bg={ctaBg} fg={ctaFg}>{hasIdentity ? "Start identity check" : "Start address check"}</WBtn></div>
        <WFooter dark={dark} />
      </div>;
  }
  if (screen === "profile") {
    return <div className="flex-1 flex flex-col min-h-0" style={bg}>
        <div className="px-5 pt-4 pb-1 flex-shrink-0">
          <button onClick={() => back("profile")} className={`w-10 h-10 rounded-full border-0 flex items-center justify-center cursor-pointer ${dark ? "bg-white/10 text-white" : "bg-black/5 text-[#0E1525]"}`}><IcoBack /></button>
        </div>
        <div className="flex-1 px-5 overflow-y-auto overflow-x-hidden">
          <h1 className="m-0 mt-1 mb-4 text-[28px] font-bold tracking-tight" style={{
      color: dark ? "#ffffff" : "#0E1525"
    }}>Personal information</h1>
            <div className="flex flex-col gap-5">
            <WField label="Full name" value="John Doe" dark={dark} readOnly hint="Enter name as it appears on the ID document." trailing={<span className={dark ? "text-white/45" : "text-[#0E1525]/40"}></span>} />
            <div>
              <label className={`block text-sm font-semibold mb-2 ${dark ? "text-white" : "text-[#0E1525]"}`}>Date of birth</label>
              <div style={{
      display: "grid",
      gridTemplateColumns: "1.5fr 0.85fr 1fr",
      gap: "0.625rem"
    }}>
                <WSelect value="January" dark={dark} rootClass="min-w-0" />
                <WField value="01" dark={dark} readOnly center rootClass="min-w-0" />
                <WField value="1980" dark={dark} readOnly center rootClass="min-w-0" />
              </div>
            </div>
            <WSelect label="Citizenship" value={country} leading={<CountryFlag region={region} />} dark={dark} />
          </div>
        </div>
        <div className="px-5 pt-4 pb-3 flex-shrink-0"><WBtn onClick={() => next("profile")} dark={dark} bg={ctaBg} fg={ctaFg}>Continue</WBtn></div>
        <WFooter dark={dark} />
      </div>;
  }
  if (screen === "address") {
    return <div className="flex-1 flex flex-col min-h-0" style={bg}>
        <div className="px-5 pt-4 pb-1 flex-shrink-0">
          <button onClick={() => back("address")} className={`w-10 h-10 rounded-full border-0 flex items-center justify-center cursor-pointer ${dark ? "bg-white/10 text-white" : "bg-black/5 text-[#0E1525]"}`}><IcoBack /></button>
        </div>
        <div className="flex-1 px-5 overflow-y-auto overflow-x-hidden">
          <h1 className="m-0 mt-1 mb-1 text-[28px] font-bold tracking-tight" style={{
      color: dark ? "#ffffff" : "#0E1525"
    }}>Address information</h1>
          <div className={`text-[15px] mb-5 ${muted}`}>Check details before continuing.</div>
          <div className="flex flex-col gap-5">
            <WField label="Home address line" value="1 High Street" dark={dark} readOnly />
            <WField label="Home address line 2 (optional)" value="Northern Quarter" dark={dark} readOnly />
            <WSelect label="Country" value={country} leading={<CountryFlag region={region} />} dark={dark} locked />
            <WSelect label="State" value="Manchester" dark={dark} />
            <WField label="City" value="Manchester" dark={dark} readOnly />
            <WField label="Zip code" value="M4 1AA" dark={dark} readOnly />
          </div>
          <div className={`text-[13px] leading-snug mt-4 ${muted}`}>Information provided is used for fraud prevention and to comply with financial regulations. It must match public records to be verified.</div>
        </div>
        <div className="px-5 pt-4 pb-3 flex-shrink-0"><WBtn onClick={() => next("address")} dark={dark} bg={ctaBg} fg={ctaFg}>Continue</WBtn></div>
        <WFooter dark={dark} />
      </div>;
  }
  if (screen === "identity") {
    const ready = ["Have a driver's license, state ID, or passport ready.", "Stay in a well-lit room.", "Allow camera and microphone access to capture a selfie and ID photos."];
    return <div className="flex-1 flex flex-col min-h-0" style={bg}>
        <div className="px-5 pt-4 pb-2 flex-shrink-0">
          <button onClick={() => back("identity")} className={`w-10 h-10 rounded-full border-0 flex items-center justify-center cursor-pointer ${dark ? "bg-white/10 text-white" : "bg-black/5 text-[#0E1525]"}`}><IcoBack /></button>
        </div>
        <div className="flex-1 px-5 overflow-y-auto overflow-x-hidden">
          <div className="flex justify-center mt-4 mb-1"><IllustrationIdDocs /></div>
          <h1 className="m-0 mt-2 mb-2 text-[28px] font-bold tracking-tight text-center" style={{
      color: dark ? "#ffffff" : "#0E1525"
    }}>Fraud and identity protection</h1>
          <div className={`text-[15px] leading-snug mb-6 text-center ${muted}`}>To protect the account, identity verification is required. Before starting, please:</div>
          <div className={`rounded-2xl p-5 ${dark ? "bg-white/[0.04]" : "bg-white"}`}>
            <div className="flex flex-col gap-4">
              {ready.map((t, i) => <div key={i} className="flex items-start gap-3.5">
                  <span className={`flex-shrink-0 ${dark ? "text-white" : "text-[#0E1525]"}`}><IcoCheckCircle /></span>
                  <span className="text-[14px] leading-snug">{t}</span>
                </div>)}
            </div>
          </div>
          <div className={`text-[13px] leading-snug mt-4 ${muted}`}>We use Veriff to verify your identity. Veriff may collect personal data, including biometric data, to confirm who you are.</div>
        </div>
        <div className="px-5 pt-4 pb-3 flex-shrink-0"><WBtn onClick={() => {
      setCaptureStep("front");
      next("identity");
    }} dark={dark} bg={ctaBg} fg={ctaFg}>Continue</WBtn></div>
        <WFooter dark={dark} />
      </div>;
  }
  if (screen === "id-capture") {
    const isBack = captureStep === "back";
    const onShutter = () => {
      if (captureStep === "front") setCaptureStep("front-shown"); else if (captureStep === "front-shown") setCaptureStep("back"); else if (captureStep === "back") {
        setCaptureStep("front");
        setSelfieShot(false);
        next("id-capture");
      }
    };
    const licenceFront = region === "US" ? <UsLicenceFront /> : region === "EU" ? <EuLicenceFront /> : <UkLicenceFront />;
    const licenceBack = region === "US" ? <UsLicenceBack /> : region === "EU" ? <EuLicenceBack /> : <UkLicenceBack />;
    return <div className="flex-1 flex flex-col min-h-0" style={{
      backgroundColor: "#101012",
      color: "#ffffff"
    }}>
        <div className="px-5 pt-4 pb-2 flex-shrink-0">
          <button onClick={() => back("id-capture")} className="w-10 h-10 -ml-1.5 rounded-full border-0 flex items-center justify-center cursor-pointer bg-transparent text-white"><IcoClose /></button>
        </div>
        <div className="px-6 mt-2">
          <h1 className="m-0 text-[22px] font-bold tracking-tight leading-snug text-white">{isBack ? "Turn your driver's license around" : "Take a photo of your document's photo page"}</h1>
        </div>
        <div className="px-5 mt-8">
          <div className="w-full rounded-2xl border border-white/25 overflow-hidden flex items-center justify-center" style={{
      aspectRatio: "1.5 / 1",
      background: "rgba(255,255,255,0.06)",
      perspective: "1000px"
    }}>
            {captureStep === "front-shown" ? licenceFront : captureStep === "back" ? <div style={{
      position: "relative",
      width: "100%",
      height: "100%",
      transformStyle: "preserve-3d",
      animation: "kw-flip 1.4s cubic-bezier(.45,0,.25,1) forwards"
    }}>
                <div style={{
      position: "absolute",
      inset: 0,
      backfaceVisibility: "hidden",
      WebkitBackfaceVisibility: "hidden"
    }}>{licenceFront}</div>
                <div style={{
      position: "absolute",
      inset: 0,
      backfaceVisibility: "hidden",
      WebkitBackfaceVisibility: "hidden",
      transform: "rotateY(180deg)"
    }}>{licenceBack}</div>
              </div> : <svg className="w-14 h-14 text-white/15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round">
                <rect x="2.5" y="5" width="19" height="14" rx="2.5" /><circle cx="8" cy="12" r="2.4" />
                <line x1="13" y1="10.5" x2="18.5" y2="10.5" /><line x1="13" y1="14" x2="17" y2="14" />
              </svg>}
          </div>
        </div>
        <div className="flex-1" />
        <div className="px-6 pb-7 flex flex-col items-center gap-5 flex-shrink-0">
          {isBack ? <div className="text-[14px] text-white/90 text-center leading-snug px-2">Turn your driver's license around and take a photo of the other side.</div> : <div className="text-center">
              <div className="text-[11px] font-bold tracking-[0.14em] text-white/55 uppercase mb-1.5">Accepted documents</div>
              <div className="text-[14px] text-white/85">Driver's license, residence permit, passport, ID card.</div>
            </div>}
          <button onClick={onShutter} aria-label="Capture" className="kw-pulse w-16 h-16 rounded-full border-[3px] border-white flex items-center justify-center cursor-pointer bg-transparent p-0">
            <span className="block rounded-full bg-white" style={{
      width: 48,
      height: 48
    }} />
          </button>
        </div>
      </div>;
  }
  if (screen === "selfie") {
    return <div className="flex-1 flex flex-col min-h-0" style={{
      backgroundColor: "#101012",
      color: "#ffffff"
    }}>
        <div className="px-5 pt-4 pb-2 flex-shrink-0">
          <button onClick={() => back("selfie")} className="w-10 h-10 -ml-1.5 rounded-full border-0 flex items-center justify-center cursor-pointer bg-transparent text-white"><IcoClose /></button>
        </div>
        <div className="px-6 mt-2">
          <h1 className="m-0 text-[22px] font-bold tracking-tight leading-snug text-white text-center">Take a selfie</h1>
        </div>
        <div className="flex-1 flex items-center justify-center px-8">
          <div className="w-full max-w-[220px] border border-white/25 overflow-hidden flex items-center justify-center" style={{
      aspectRatio: "0.8 / 1",
      borderRadius: "50%",
      background: "rgba(255,255,255,0.06)"
    }}>
            {selfieShot ? <SelfiePortrait /> : <svg className="w-20 h-20 text-white/15" viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="9" r="4.2" /><path d="M4.5 21a7.5 7.5 0 0 1 15 0z" /></svg>}
          </div>
        </div>
        <div className="px-6 pb-7 flex flex-col items-center gap-5 flex-shrink-0">
          <div className="text-[14px] text-white/90 text-center leading-snug px-2">{selfieShot ? "Looks good — tap again to continue." : "Position your face in the oval and hold still."}</div>
          <button onClick={() => {
      if (!selfieShot) setSelfieShot(true); else next("selfie");
    }} aria-label="Capture" className="kw-pulse w-16 h-16 rounded-full border-[3px] border-white flex items-center justify-center cursor-pointer bg-transparent p-0">
            <span className="block rounded-full bg-white" style={{
      width: 48,
      height: 48
    }} />
          </button>
        </div>
      </div>;
  }
  if (screen === "poa-intro") {
    const cardBg = dark ? "rgba(255,255,255,0.04)" : "#ffffff";
    const cardBorder = dark ? "rgba(255,255,255,0.1)" : "rgba(14,21,37,0.1)";
    const pillBorder = dark ? "rgba(255,255,255,0.2)" : "rgba(14,21,37,0.15)";
    return <div className="flex-1 flex flex-col min-h-0" style={bg}>
        <div className="px-5 pt-4 pb-2 flex-shrink-0">
          <button onClick={onBack} className={`w-10 h-10 rounded-full border-0 flex items-center justify-center cursor-pointer ${dark ? "bg-white/10 text-white" : "bg-black/5 text-[#0E1525]"}`}><IcoClose /></button>
        </div>
        <div className="px-5 pb-3 flex-1 flex flex-col min-h-0">
          <div className="flex-1 rounded-3xl p-5 flex flex-col min-h-0" style={{
      background: cardBg,
      border: `1px solid ${cardBorder}`
    }}>
            <div className="flex justify-end flex-shrink-0">
              <div className="flex items-center gap-1.5 rounded-full px-3 py-1.5 text-[13px] font-semibold" style={{
      border: `1px solid ${pillBorder}`,
      color: bg.color
    }}>
                <IcoGlobe /> En
              </div>
            </div>
            <div className="flex-1 flex flex-col items-center justify-center text-center px-1">
              <UpholdLogo />
              <h1 className="m-0 mt-7 mb-3 text-[24px] font-bold tracking-tight" style={{
      color: bg.color
    }}>"Uphold" verification</h1>
              <div className="text-[14px] leading-relaxed" style={{
      color: dark ? "rgba(255,255,255,0.7)" : "rgba(14,21,37,0.7)"
    }}>You're about to submit sensitive data to "Uphold". If you received this link from a suspicious source, please close this page and notify us immediately.</div>
            </div>
            <div className="flex-shrink-0 pt-4"><WBtn onClick={() => {
      setPoaFile(false);
      next("poa-intro");
    }} dark={dark} bg={ctaBg} fg={ctaFg}>Continue</WBtn></div>
          </div>
        </div>
        <WFooter dark={dark} />
      </div>;
  }
  if (screen === "poa") {
    const cardBg = dark ? "rgba(255,255,255,0.04)" : "#ffffff";
    const cardBorder = dark ? "rgba(255,255,255,0.1)" : "rgba(14,21,37,0.1)";
    const pillBorder = dark ? "rgba(255,255,255,0.2)" : "rgba(14,21,37,0.15)";
    const dashBorder = dark ? "rgba(255,255,255,0.22)" : "rgba(14,21,37,0.2)";
    const link = dark ? "#7AA2FF" : "#2563EB";
    const docTypes = ["Valid ID document with address details", "Bank documents (last 2 months)", "Utility bills (last 2 months)", "Government-issued documents (last 2 months)"];
    return <div className="flex-1 flex flex-col min-h-0" style={bg}>
        <div className="px-5 pt-4 pb-2 flex-shrink-0">
          <button onClick={onBack} className={`w-10 h-10 rounded-full border-0 flex items-center justify-center cursor-pointer ${dark ? "bg-white/10 text-white" : "bg-black/5 text-[#0E1525]"}`}><IcoClose /></button>
        </div>
        <div className="px-5 pb-2 flex items-center gap-3 flex-shrink-0">
          <button onClick={() => back("poa")} className="w-9 h-9 rounded-full flex items-center justify-center cursor-pointer bg-transparent" style={{
      border: `1px solid ${pillBorder}`,
      color: bg.color
    }}><IcoBack /></button>
          <span className="text-[15px] font-bold" style={{
      color: bg.color
    }}>Step</span>
          <div className="w-9 h-9 rounded-full flex items-center justify-center text-[12px] font-bold" style={{
      border: `1px solid ${pillBorder}`,
      color: bg.color
    }}>1/1</div>
          <div className="flex-1" />
          <div className="flex items-center gap-1.5 rounded-full px-3 py-1.5 text-[13px] font-semibold" style={{
      border: `1px solid ${pillBorder}`,
      color: bg.color
    }}><IcoGlobe /> En</div>
        </div>
        <div className="px-5 pb-3 flex-1 flex flex-col min-h-0">
          <div className="flex-1 rounded-3xl flex flex-col min-h-0 overflow-hidden" style={{
      background: cardBg,
      border: `1px solid ${cardBorder}`
    }}>
            <div className="flex-1 overflow-y-auto px-5 pt-5">
              <h1 className="m-0 mb-1.5 text-[24px] font-bold tracking-tight leading-tight" style={{
      color: bg.color
    }}>Upload a document to confirm your address</h1>
              <div className={`text-[14px] mb-4 ${muted}`}>The document must show your address</div>
              {poaFile ? <div className="w-full rounded-2xl border-[1.5px] flex items-center gap-3.5 p-3.5" style={{
      borderColor: "#35B13D",
      background: dark ? "rgba(53,177,61,0.1)" : "rgba(53,177,61,0.07)"
    }}>
                  <div className="w-12 h-12 rounded-xl flex items-center justify-center flex-shrink-0 bg-[#35B13D] text-white"><IcoDoc /></div>
                  <div className="flex-1 min-w-0">
                    <div className="text-[14px] font-bold truncate" style={{
      color: bg.color
    }}>proof-of-address.pdf</div>
                    <div className={`text-[12px] mt-0.5 ${muted}`}>1.2 MB · Ready to upload</div>
                  </div>
                  <button onClick={() => setPoaFile(false)} aria-label="Remove file" className="flex-shrink-0 bg-transparent border-0 cursor-pointer" style={{
      color: bg.color,
      opacity: 0.55
    }}><IcoXCircle /></button>
                </div> : <button onClick={() => setPoaFile(true)} className="kw-pulse w-full rounded-2xl border-[1.5px] border-dashed flex items-center gap-3.5 p-3.5 cursor-pointer bg-transparent text-left" style={{
      borderColor: dashBorder
    }}>
                  <div className="w-12 h-12 rounded-xl flex items-center justify-center flex-shrink-0" style={{
      background: dark ? "rgba(255,255,255,0.06)" : "rgba(14,21,37,0.05)",
      color: bg.color
    }}>
                    <svg className="w-6 h-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="M7 18a4 4 0 0 1-.5-7.97A5.5 5.5 0 0 1 17 9.5a3.5 3.5 0 0 1 .5 6.96" /><path d="M12 12v7M9 15l3-3 3 3" /></svg>
                  </div>
                  <div className="min-w-0">
                    <div className="text-[15px] font-bold flex items-center gap-1" style={{
      color: bg.color
    }}>Document <span style={{
      color: "#E5563B"
    }}>*</span></div>
                    <div className="text-[13px] mt-0.5"><span style={{
      color: link
    }} className="font-semibold">Choose</span> <span className={muted}>or drag and drop</span></div>
                  </div>
                </button>}
              <div className={`text-[12px] text-center mt-2.5 ${muted}`}>JPG, PNG, HEIC, WEBP or PDF (max 50 MB)</div>
              <div className="text-[16px] font-bold mt-6 mb-3" style={{
      color: bg.color
    }}>Document types</div>
              <div className="flex flex-col gap-2.5">
                {docTypes.map((t, i) => <div key={i} className="flex gap-3 text-[14px]" style={{
      color: bg.color
    }}>
                    <span className="flex-shrink-0" style={{
      opacity: 0.6
    }}>•</span><span className="leading-snug">{t}</span>
                  </div>)}
              </div>
              <div className="mt-4 mb-5 text-[14px] font-semibold" style={{
      color: link
    }}>What else can I upload?</div>
            </div>
            <div className="flex-shrink-0 px-5 pt-3 pb-5 flex flex-col gap-2.5">
              <WBtn onClick={() => next("poa")} dark={dark} bg={ctaBg} fg={ctaFg} disabled={!poaFile}>Upload document</WBtn>
              <button onClick={poaFile ? () => next("poa") : undefined} disabled={!poaFile} style={{
      height: "3rem",
      padding: 0,
      border: `1.5px solid ${pillBorder}`,
      color: bg.color,
      opacity: poaFile ? 1 : 0.4
    }} className={`w-full rounded-full text-[15px] font-bold bg-transparent ${poaFile ? "cursor-pointer" : "cursor-not-allowed"}`}>Continue on phone</button>
            </div>
          </div>
        </div>
        <WFooter dark={dark} />
      </div>;
  }
  return <div className="flex-1 flex flex-col items-center justify-center px-8 text-center" style={bg}>
      <div className="kw-spinner" style={{
    borderTopColor: "#35B13D"
  }} />
      <div className="text-[18px] font-bold mt-6">Submitting your information…</div>
      <div className={`text-[13px] mt-2 ${muted}`}>Hang tight — this only takes a moment.</div>
    </div>;
};

export const FLOW_STEPS = {
  "all": ["profile", "address", "verify-intro", "identity", "id-capture", "selfie"],
  "identity-poa": ["verify-intro", "identity", "id-capture", "selfie"],
  "proof-of-address": ["verify-intro", "poa-intro", "poa"]
};

export const PickTile = ({icon, title, sub, selected, onClick, dark}) => <button onClick={onClick} className={`flex items-center gap-4 w-full px-3.5 py-3.5 rounded-2xl text-left border-[1.5px] transition-colors cursor-pointer
      ${selected ? "border-[#35B13D]" : dark ? "border-white/10 bg-white/[0.04] hover:bg-white/[0.08]" : "border-black/5 bg-white hover:bg-white/80"}`} style={selected ? {
  background: dark ? "rgba(53,177,61,0.12)" : "rgba(53,177,61,0.08)"
} : undefined}>
    <div className={`w-11 h-11 rounded-full flex items-center justify-center flex-shrink-0 ${dark ? "bg-[#3A3D42] text-white" : "bg-black/5 text-[#0E1525]"}`}>{icon}</div>
    <div className="flex-1 min-w-0">
      <div className={`text-[14px] font-bold ${dark ? "text-white" : "text-[#0E1525]"}`}>{title}</div>
      {sub && <div className={`text-[12px] mt-0.5 ${dark ? "text-white/55" : "text-[#0E1525]/55"}`}>{sub}</div>}
    </div>
    <div className={`w-5 h-5 rounded-full flex items-center justify-center flex-shrink-0 ${selected ? "bg-[#35B13D] text-white" : dark ? "border-[1.5px] border-white/25" : "border-[1.5px] border-black/15"}`}>
      {selected && <IcoCheckSm />}
    </div>
  </button>;

export const WSelect = ({label, value, leading, dark, rootClass, locked}) => <div className={rootClass || "flex-1 min-w-0"}>
    {label && <label className={`block text-sm font-semibold mb-2 ${locked ? dark ? "text-white/40" : "text-[#0E1525]/40" : dark ? "text-white" : "text-[#0E1525]"}`}>{label}</label>}
    <div className={`flex items-center gap-2.5 px-3.5 h-12 rounded-xl border-[1.5px] ${locked ? "" : "cursor-pointer"} ${dark ? "border-white/20 bg-white/[0.04]" : "border-[#0E1525]/15 bg-white"}`}>
      {leading}
      <span className={`flex-1 min-w-0 text-[15px] truncate ${dark ? "text-white" : "text-[#0E1525]"}`}>{value}</span>
      <span className={locked ? dark ? "text-white/30" : "text-[#0E1525]/30" : dark ? "text-white/60" : "text-[#0E1525]/55"}><IcoChevronDown /></span>
    </div>
  </div>;

export const WField = ({label, value, onChange, placeholder, dark, readOnly, leading, trailing, hint, rootClass, center}) => <div className={rootClass || "flex-1 min-w-0"}>
    {label && <label className={`block text-sm font-semibold mb-2 ${dark ? "text-white" : "text-[#0E1525]"}`}>{label}</label>}
    <div className={`flex items-center gap-2.5 px-3.5 h-12 rounded-xl border-[1.5px] ${dark ? "border-white/20 bg-white/[0.04]" : "border-[#0E1525]/15 bg-white"}`}>
      {leading}
      <input value={value} onChange={onChange} placeholder={placeholder} readOnly={readOnly} className={`flex-1 min-w-0 border-0 outline-none bg-transparent text-[15px] font-sans ${center ? "text-center" : ""} ${dark ? "text-white" : "text-[#0E1525]"}`} />
      {trailing}
    </div>
    {hint && <div className={`text-[12px] mt-1.5 ${dark ? "text-white/55" : "text-[#0E1525]/55"}`}>{hint}</div>}
  </div>;

export const WBtn = ({onClick, dark, children, disabled, bg, fg}) => <button onClick={disabled ? undefined : onClick} disabled={disabled} style={{
  height: "3rem",
  padding: 0,
  ...bg ? {
    background: bg,
    color: fg
  } : {}
}} className={`w-full border-0 rounded-full text-[15px] font-bold transition-colors ${disabled ? "opacity-40 cursor-not-allowed" : "cursor-pointer kw-pulse"} ${bg ? "" : dark ? "bg-white text-[#0E1525] hover:bg-white/90" : "bg-[#0E1525] text-white hover:bg-[#0E1525]/90"}`}>
    {children}
  </button>;

export const WFooter = ({dark}) => <div className={`flex items-center justify-center gap-2.5 px-5 pt-4 pb-5 flex-shrink-0 text-sm ${dark ? "text-white/55" : "text-[#0E1525]/50"}`}>
    <LeafLogo />
    <div className={`w-px h-3.5 ${dark ? "bg-white/20" : "bg-[#0E1525]/15"}`} />
    <span>Powered by <strong style={{
  color: dark ? "#ffffff" : "#0E1525"
}}>Uphold</strong></span>
  </div>;

export const WTopBar = ({onBack, title, dark, step, total}) => <div className="flex items-center gap-3 px-5 pt-4 pb-3 flex-shrink-0">
    <button onClick={onBack} className={`w-10 h-10 rounded-full border-0 flex items-center justify-center cursor-pointer ${dark ? "bg-white/10 text-white" : "bg-black/5 text-[#0E1525]"}`}>
      <IcoBack />
    </button>
    {total > 0 && <div className="flex-1 flex items-center gap-1.5">
        {Array.from({
  length: total
}).map((_, i) => <div key={i} className="flex-1 h-[3px] rounded-full" style={{
  background: i < step ? "#35B13D" : dark ? "rgba(255,255,255,0.15)" : "rgba(14,21,37,0.12)"
}} />)}
      </div>}
    {title && total === 0 && <div className={`flex-1 text-center pr-10 text-[17px] font-semibold ${dark ? "text-white" : "text-[#0E1525]"}`}>{title}</div>}
  </div>;

export const NavTab = ({label, d, active, dark, accent}) => {
  const colorOn = dark ? "text-white" : accent || "text-[#1d2738]";
  const colorOff = dark ? "text-white/35" : "text-[#0E1525]/35";
  return <button className={`flex flex-col items-center gap-0.5 border-0 bg-transparent cursor-pointer ${active ? colorOn : colorOff}`} style={accent && active ? {
    color: accent
  } : undefined}>
      <svg className="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d={d} /></svg>
      <span className="text-[10px] font-bold">{label}</span>
    </button>;
};

export const PhoneShell = ({children, bgClass = "bg-[#FAFAF7]", lightStatus = true, borderClass = "border-black/10"}) => <div className={`relative w-[320px] sm:w-[360px] h-[720px] rounded-[40px] sm:rounded-[44px] overflow-hidden border-2 flex flex-col font-sans shadow-[0_48px_96px_-28px_rgba(11,15,30,0.45),0_8px_20px_-6px_rgba(11,15,30,0.18)] ${bgClass} ${borderClass}`}>
    <div className={`absolute top-2 left-1/2 -translate-x-1/2 w-[110px] h-7 rounded-full z-10 ${lightStatus ? "bg-black" : "bg-white/20"}`} />
    <StatusBar light={lightStatus} />
    <div className="flex-1 flex flex-col min-h-0 relative">{children}</div>
    <div className="absolute bottom-2 left-1/2 -translate-x-1/2 w-[134px] h-[5px] rounded-full z-20" style={{
  background: lightStatus ? "rgba(14,21,37,0.2)" : "rgba(255,255,255,0.4)"
}} />
  </div>;

export const StatusBar = ({light}) => <div className="h-11 flex items-center justify-between px-7 flex-shrink-0 text-[15px] font-semibold" style={{
  color: light ? "#0E1525" : "white",
  backgroundColor: light ? "white" : "black"
}}>
    <span>9:41</span>
    <div className="flex items-center gap-1.5">
      <svg className="w-[18px] h-3" viewBox="0 0 18 12" fill="currentColor"><rect x="0" y="8" width="3" height="4" rx="0.5" /><rect x="5" y="5" width="3" height="7" rx="0.5" /><rect x="10" y="2" width="3" height="10" rx="0.5" /><rect x="15" y="0" width="3" height="12" rx="0.5" /></svg>
      <svg className="w-4 h-3" viewBox="0 0 16 12" fill="none" stroke="currentColor" strokeWidth="1.4"><path d="M1,5 Q8,-1 15,5" /><path d="M3.5,7 Q8,3 12.5,7" /><circle cx="8" cy="9.5" r="1" fill="currentColor" /></svg>
      <svg className="w-[26px] h-3" viewBox="0 0 26 12" fill="none"><rect x="0.5" y="0.5" width="22" height="11" rx="2.5" stroke="currentColor" strokeOpacity="0.5" /><rect x="2" y="2" width="19" height="8" rx="1.5" fill="currentColor" /><rect x="23" y="4" width="2" height="4" rx="1" fill="currentColor" fillOpacity="0.5" /></svg>
    </div>
  </div>;

export const CountryFlag = ({region}) => region === "US" ? <UsFlag /> : region === "EU" ? <EuFlag /> : <UkFlag />;

export const EuFlag = () => <svg className="w-6 h-6 rounded-full block flex-shrink-0" viewBox="0 0 60 60">
    <rect width="60" height="60" fill="#003399" />
    {Array.from({
  length: 12
}).map((_, i) => {
  const a = (i * 30 - 90) * Math.PI / 180;
  return <circle key={i} cx={30 + Math.cos(a) * 18} cy={30 + Math.sin(a) * 18} r="2.4" fill="#FFCC00" />;
})}
  </svg>;

export const UsFlag = () => <svg className="w-6 h-6 rounded-full block flex-shrink-0" viewBox="0 0 60 60" preserveAspectRatio="xMidYMid slice">
    <rect width="60" height="60" fill="#fff" />
    {[0, 2, 4, 6, 8, 10, 12].map(i => <rect key={i} y={i * 60 / 13} width="60" height={60 / 13} fill="#B22234" />)}
    <rect width="26" height={60 * 7 / 13} fill="#3C3B6E" />
  </svg>;

export const UkFlag = () => <svg className="w-6 h-6 rounded-full block flex-shrink-0" viewBox="0 0 60 60">
    <rect width="60" height="60" fill="#012169" />
    <path d="M0,0 L60,60 M60,0 L0,60" stroke="#fff" strokeWidth="9" />
    <path d="M0,0 L60,60 M60,0 L0,60" stroke="#C8102E" strokeWidth="3.6" />
    <path d="M30,0 V60 M0,30 H60" stroke="#fff" strokeWidth="15" />
    <path d="M30,0 V60 M0,30 H60" stroke="#C8102E" strokeWidth="7.5" />
  </svg>;

export const LeafLogo = ({color = "#35B13D"}) => <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 18" className="w-3.5 h-[18px]">
    <path fill={color} fillRule="evenodd" clipRule="evenodd" d="M11.622 9.986a9.52 9.52 0 0 1-1.536 2.343c.427-1.588.221-3.64-.702-5.631a9.941 9.941 0 0 0-1.866-2.741c1.163-.89 2.373-1.181 3.308-.771.6.262 1.062.8 1.337 1.555.521 1.43.319 3.39-.541 5.245Zm-9.744 0C1.018 8.131.815 6.17 1.337 4.741c.275-.755.737-1.293 1.337-1.555.935-.41 2.145-.12 3.308.77a9.924 9.924 0 0 0-1.866 2.742c-.924 1.992-1.13 4.043-.703 5.631a9.506 9.506 0 0 1-1.535-2.343Zm5.744 4.02c-.269.117-.562.178-.872.182a2.224 2.224 0 0 1-.872-.183c-1.801-.789-2.165-3.95-.796-6.905A8.948 8.948 0 0 1 6.75 4.642 8.926 8.926 0 0 1 8.417 7.1c1.37 2.953 1.006 6.115-.795 6.904Zm2.445-11.999C9 1.965 7.837 2.397 6.75 3.261 5.663 2.398 4.5 1.964 3.433 2.006a5.903 5.903 0 0 1 3.316-1.005c1.226 0 2.377.367 3.318 1.006Zm3.098 2.42v-.003l-.003-.006a.02.02 0 0 1-.001-.005l-.004-.01C12.255 1.77 9.684 0 6.749 0 3.807 0 1.23 1.778.334 4.424c-.001.004-.001.009-.003.013-.595 1.66-.38 3.882.58 5.952C2.226 13.223 4.61 15.19 6.72 15.19h.06c2.11 0 4.495-1.968 5.808-4.8.962-2.075 1.177-4.302.577-5.963Zm-4.61 12.321a6.517 6.517 0 0 1-1.757.25h-.084a6.53 6.53 0 0 1-1.768-.253.533.533 0 0 0-.657.337.497.497 0 0 0 .356.623 7.64 7.64 0 0 0 2.07.295h.083c.674 0 1.367-.098 2.056-.291a.497.497 0 0 0 .357-.623.533.533 0 0 0-.656-.338Z" />
  </svg>;

export const AutoBadge = () => <span className="inline-flex items-center justify-center w-6 h-6 rounded-full flex-shrink-0" style={{
  background: "#6B7280"
}}>
    <svg className="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3.5 12a8.5 8.5 0 0 1 14-6.5" /><polyline points="18.5 2 18.5 6.5 14 6.5" /><path d="M20.5 12a8.5 8.5 0 0 1-14 6.5" /><polyline points="5.5 22 5.5 17.5 10 17.5" /></svg>
  </span>;

export const ClockBadge = () => <span className="inline-flex items-center justify-center w-6 h-6 rounded-full flex-shrink-0" style={{
  background: "#2563EB"
}}>
    <svg className="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="9" /><polyline points="12 7.5 12 12 15 14" /></svg>
  </span>;

export const SelfiePortrait = () => <svg viewBox="0 0 200 250" className="w-full h-full block" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
    <defs>
      <linearGradient id="kwSelfieBg" x1="0" y1="0" x2="0" y2="1">
        <stop offset="0%" stopColor="#5C6B78" /><stop offset="100%" stopColor="#3C4751" />
      </linearGradient>
    </defs>
    <rect width="200" height="250" fill="url(#kwSelfieBg)" />
    {}
    <path d="M34 250 Q36 192 100 184 Q164 192 166 250 Z" fill="#2B333B" />
    {}
    <path d="M84 150 h32 v22 q0 14 -16 16 q-16 -2 -16 -16 z" fill="#D7A077" />
    {}
    <ellipse cx="100" cy="108" rx="45" ry="51" fill="#E6B98C" />
    {}
    <circle cx="56" cy="112" r="8" fill="#E0AE80" />
    <circle cx="144" cy="112" r="8" fill="#E0AE80" />
    {}
    <path d="M53 104 Q52 52 100 50 Q148 52 147 104 Q150 80 128 66 Q114 56 100 56 Q86 56 72 66 Q50 80 53 104 Z" fill="#2A2320" />
    {}
    <path d="M68 96 q12 -6 24 -1" stroke="#2A2320" strokeWidth="4" fill="none" strokeLinecap="round" />
    <path d="M108 95 q12 -5 24 1" stroke="#2A2320" strokeWidth="4" fill="none" strokeLinecap="round" />
    {}
    <g stroke="#15171A" strokeWidth="2.6" fill="rgba(255,255,255,0.06)">
      <rect x="64" y="103" width="30" height="22" rx="9" />
      <rect x="106" y="103" width="30" height="22" rx="9" />
      <line x1="94" y1="111" x2="106" y2="111" />
    </g>
    {}
    <circle cx="79" cy="114" r="3" fill="#3A2E28" />
    <circle cx="121" cy="114" r="3" fill="#3A2E28" />
    {}
    <path d="M100 120 l-5 16 q5 4 10 0 z" fill="#D29B72" />
    {}
    <path d="M57 116 Q60 168 100 176 Q140 168 143 116 Q139 152 100 158 Q61 152 57 116 Z" fill="#2A2320" />
    {}
    <path d="M86 144 q14 8 28 0" stroke="#8A5341" strokeWidth="2.6" fill="none" strokeLinecap="round" />
  </svg>;

export const EuLicenceBack = () => <svg viewBox="0 0 340 214" className="w-full h-full block" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
    <rect width="340" height="214" fill="#F3E7EC" />
    <rect x="0" y="0" width="8" height="214" fill="#0B3D91" />
    <rect x="20" y="18" width="214" height="16" fill="#E3C3D1" />
    {["9", "10", "11", "12"].map((c, i) => <text key={c} x={30 + i * 52} y={30} fontFamily="Arial, sans-serif" fontSize="9" fontWeight="700" fill="#7A2E48">{c}</text>)}
    {["AM", "A1", "A", "B", "BE", "C1", "C"].map((cat, r) => <g key={cat}>
        <line x1="20" y1={34 + r * 15} x2="234" y2={34 + r * 15} stroke="#D9B6C6" strokeWidth="1" />
        <text x="24" y={45 + r * 15} fontFamily="Arial, sans-serif" fontSize="7.5" fill="#9B6B7E">{cat}</text>
        {[0, 1, 2].map(c => <rect key={c} x={70 + c * 52} y={39 + r * 15} width="38" height="6" rx="3" fill="#C98DA6" opacity="0.7" />)}
      </g>)}
    {[20, 64, 116, 168, 234].map((x, i) => <line key={i} x1={x} y1="18" x2={x} y2="139" stroke="#D9B6C6" strokeWidth="1" />)}
    <g transform="translate(250, 22)">
      <rect x="0" y="0" width="74" height="118" rx="3" fill="#ffffff" opacity="0.6" />
      {Array.from({
  length: 25
}).map((_, i) => <rect key={i} x={6 + i * 2.6} y="8" width={i % 3 === 0 ? 2 : 1} height="80" fill="#3A2A31" />)}
      <rect x="6" y="96" width="62" height="6" rx="2" fill="#7A2E48" opacity="0.5" />
    </g>
    <rect x="20" y="156" width="200" height="7" rx="3.5" fill="#C98DA6" opacity="0.6" />
    <rect x="20" y="170" width="150" height="7" rx="3.5" fill="#C98DA6" opacity="0.45" />
  </svg>;

export const EuLicenceFront = () => <svg viewBox="0 0 340 214" className="w-full h-full block" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
    <defs>
      <linearGradient id="kwEuBg" x1="0" y1="0" x2="1" y2="1">
        <stop offset="0%" stopColor="#F8D7E2" /><stop offset="100%" stopColor="#EBC0D2" />
      </linearGradient>
    </defs>
    <rect width="340" height="214" fill="url(#kwEuBg)" />
    <rect x="0" y="0" width="36" height="214" fill="#0B3D91" />
    {Array.from({
  length: 12
}).map((_, i) => {
  const a = (i * 30 - 90) * Math.PI / 180;
  return <circle key={i} cx={18 + Math.cos(a) * 11} cy={34 + Math.sin(a) * 11} r="1.5" fill="#FFD64A" />;
})}
    <text x="18" y="118" fontFamily="Arial, sans-serif" fontWeight="800" fontSize="15" fill="#ffffff" textAnchor="middle">D</text>
    <text x="50" y="26" fontFamily="Arial, sans-serif" fontWeight="700" fontSize="13" fill="#7A2E48">FÜHRERSCHEIN</text>
    <text x="50" y="40" fontFamily="Arial, sans-serif" fontWeight="600" fontSize="7.5" fill="#9B6B7E">DRIVING LICENCE · EU</text>
    <rect x="50" y="52" width="72" height="92" rx="4" fill="#E7DEE4" />
    <circle cx="86" cy="84" r="16" fill="#C7BAC4" />
    <path d="M62 136 a24 21 0 0 1 48 0 Z" fill="#C7BAC4" />
    {["1.", "2.", "3.", "4a.", "4b.", "5."].map((n, i) => <g key={n} transform={`translate(134, ${62 + i * 15})`}>
        <text x="0" y="0" fontFamily="Arial, sans-serif" fontSize="7" fontWeight="700" fill="#9B6B7E">{n}</text>
        <rect x="22" y="-6" width={140 - i % 3 * 24} height="6" rx="3" fill="#C98DA6" />
      </g>)}
    <rect x="50" y="152" width="72" height="40" rx="4" fill="#ffffff" opacity="0.35" />
  </svg>;

export const UsLicenceBack = () => <svg viewBox="0 0 340 214" className="w-full h-full block" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
    <rect width="340" height="214" fill="#E9EDF2" />
    <rect x="16" y="20" width="308" height="92" rx="3" fill="#ffffff" />
    {Array.from({
  length: 90
}).map((_, i) => <rect key={i} x={22 + i * 3.3} y="28" width={i % 4 === 0 ? 2.4 : 1.2} height="76" fill="#1C2630" />)}
    {[0, 1, 2].map(i => <rect key={i} x="16" y={130 + i * 16} width={250 - i * 44} height="7" rx="3.5" fill="#B9C4D0" />)}
    <rect x="250" y="150" width="74" height="44" rx="4" fill="#D8E0EA" />
  </svg>;

export const UsLicenceFront = () => <svg viewBox="0 0 340 214" className="w-full h-full block" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
    <rect width="340" height="214" fill="#EEF2F7" />
    <rect width="340" height="42" fill="#15396E" />
    <text x="16" y="20" fontFamily="Arial, sans-serif" fontWeight="800" fontSize="13" fill="#ffffff">CALIFORNIA</text>
    <text x="16" y="34" fontFamily="Arial, sans-serif" fontWeight="600" fontSize="9" fill="#9FBCE8">USA</text>
    <path d="M315 9 l3.2 6.6 7.3 1.1 -5.3 5.1 1.3 7.2 -6.5 -3.4 -6.5 3.4 1.3 -7.2 -5.3 -5.1 7.3 -1.1 z" fill="#E7B23B" />
    <text x="16" y="62" fontFamily="Arial, sans-serif" fontWeight="700" fontSize="11" fill="#15396E">DRIVER LICENSE</text>
    <rect x="16" y="74" width="76" height="98" rx="4" fill="#D8E0EA" />
    <circle cx="54" cy="108" r="17" fill="#AEBED0" />
    <path d="M30 164 a24 21 0 0 1 48 0 Z" fill="#AEBED0" />
    {["DL", "LN", "FN", "DOB", "EXP"].map((l, i) => <g key={l} transform={`translate(104, ${84 + i * 17})`}>
        <text x="0" y="0" fontFamily="Arial, sans-serif" fontSize="8" fontWeight="700" fill="#5C7A9E">{l}</text>
        <rect x="34" y="-7" width={150 - i % 3 * 24} height="6" rx="3" fill="#9FB6CE" />
      </g>)}
    <rect x="104" y="178" width="120" height="8" rx="4" fill="#9FB6CE" opacity="0.6" />
  </svg>;

export const UkLicenceBack = () => <svg viewBox="0 0 340 214" className="w-full h-full block" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
    <rect width="340" height="214" fill="#F3E7EC" />
    {}
    <rect x="16" y="18" width="218" height="16" fill="#E3C3D1" />
    {["9", "10", "11", "12"].map((c, i) => <text key={c} x={26 + i * 52} y={30} fontFamily="Arial, sans-serif" fontSize="9" fontWeight="700" fill="#7A2E48">{c}</text>)}
    {["AM", "A1", "A", "B1", "B", "BE", "C1"].map((cat, r) => <g key={cat}>
        <line x1="16" y1={34 + r * 15} x2="234" y2={34 + r * 15} stroke="#D9B6C6" strokeWidth="1" />
        <text x="20" y={45 + r * 15} fontFamily="Arial, sans-serif" fontSize="7.5" fill="#9B6B7E">{cat}</text>
        {[0, 1, 2].map(c => <rect key={c} x={66 + c * 52} y={39 + r * 15} width="38" height="6" rx="3" fill="#C98DA6" opacity="0.7" />)}
      </g>)}
    {[16, 60, 112, 164, 234].map((x, i) => <line key={i} x1={x} y1="18" x2={x} y2="139" stroke="#D9B6C6" strokeWidth="1" />)}
    {}
    <g transform="translate(250, 22)">
      <rect x="0" y="0" width="74" height="118" rx="3" fill="#ffffff" opacity="0.6" />
      {Array.from({
  length: 25
}).map((_, i) => <rect key={i} x={6 + i * 2.6} y="8" width={i % 3 === 0 ? 2 : 1} height="80" fill="#3A2A31" />)}
      <rect x="6" y="96" width="62" height="6" rx="2" fill="#7A2E48" opacity="0.5" />
    </g>
    <rect x="16" y="156" width="200" height="7" rx="3.5" fill="#C98DA6" opacity="0.6" />
    <rect x="16" y="170" width="150" height="7" rx="3.5" fill="#C98DA6" opacity="0.45" />
  </svg>;

export const UkLicenceFront = () => <svg viewBox="0 0 340 214" className="w-full h-full block" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
    <defs>
      <linearGradient id="kwDlBg" x1="0" y1="0" x2="1" y2="1">
        <stop offset="0%" stopColor="#F8D7E2" /><stop offset="55%" stopColor="#FBEAF0" /><stop offset="100%" stopColor="#EFC6D6" />
      </linearGradient>
    </defs>
    <rect width="340" height="214" fill="url(#kwDlBg)" />
    <path d="M232 30 q40 26 14 74 q-22 40 26 80" stroke="#E3A9C0" strokeWidth="2.5" fill="none" opacity="0.45" />
    <path d="M262 18 q34 30 8 86" stroke="#E3A9C0" strokeWidth="2" fill="none" opacity="0.35" />
    <text x="16" y="30" fontFamily="Arial, sans-serif" fontWeight="700" fontSize="15" fill="#7A2E48">DRIVING LICENCE</text>
    {}
    <rect x="296" y="12" width="32" height="44" rx="4" fill="#0B3D91" />
    {Array.from({
  length: 8
}).map((_, i) => {
  const a = (i * 45 - 90) * Math.PI / 180;
  return <circle key={i} cx={312 + Math.cos(a) * 8} cy={28 + Math.sin(a) * 8} r="1.1" fill="#FFD64A" />;
})}
    <text x="312" y="50" fontFamily="Arial, sans-serif" fontWeight="700" fontSize="9" fill="#fff" textAnchor="middle">GB</text>
    {}
    <rect x="16" y="46" width="74" height="94" rx="5" fill="#E7DEE4" />
    <circle cx="53" cy="80" r="17" fill="#C7BAC4" />
    <path d="M29 132 a24 21 0 0 1 48 0 Z" fill="#C7BAC4" />
    {}
    {["SURNAME", "FIRST NAMES", "DATE OF BIRTH", "ISSUE DATE", "EXPIRY", "LICENCE NO."].map((f, i) => <g key={i} transform={`translate(104, ${56 + i * 15})`}>
        <text x="0" y="0" fontFamily="Arial, sans-serif" fontSize="6" fontWeight="700" fill="#9B6B7E">{i + 1}. {f}</text>
        <rect x="0" y="3" width={150 - i % 3 * 26} height="6" rx="3" fill="#C98DA6" />
      </g>)}
    {}
    <rect x="104" y="150" width="120" height="9" rx="4.5" fill="#C98DA6" opacity="0.65" />
    <rect x="16" y="150" width="74" height="44" rx="4" fill="#ffffff" opacity="0.35" />
  </svg>;

export const IllustrationChecklist = () => <svg viewBox="0 0 260 220" className="w-[200px] h-[168px]" fill="none" xmlns="http://www.w3.org/2000/svg">
    <defs>
      <linearGradient id="kwClipGrad" x1="0" y1="0" x2="0" y2="1">
        <stop offset="0%" stopColor="#FDFDFE" /><stop offset="100%" stopColor="#E0E0E6" />
      </linearGradient>
    </defs>
    <ellipse cx="132" cy="200" rx="78" ry="12" fill="#1A1410" opacity="0.06" />
    <g transform="rotate(-5 130 110)">
      <rect x="72" y="24" width="122" height="160" rx="13" fill="url(#kwClipGrad)" stroke="#D4D4DB" strokeWidth="1.5" />
      {[50, 96, 142].map((y, i) => <g key={y}>
          <rect x="90" y={y} width="30" height="30" rx="7" fill="#F0F0F4" stroke="#D0D0D7" strokeWidth="1.4" />
          {i < 2 && <path d={`M97 ${y + 15} l5 5 9-11`} stroke="#35B13D" strokeWidth="3.4" fill="none" strokeLinecap="round" strokeLinejoin="round" />}
          <rect x="132" y={y + 6} width="48" height="9" rx="4.5" fill={i < 2 ? "#CFCFD6" : "#D8D8DF"} />
          <rect x="132" y={y + 19} width="34" height="7" rx="3.5" fill={i < 2 ? "#DEDEE4" : "#E4E4E9"} />
        </g>)}
    </g>
  </svg>;

export const IllustrationIdDocs = () => <svg viewBox="0 0 240 184" className="w-[208px] h-[160px]" fill="none" xmlns="http://www.w3.org/2000/svg">
    <defs>
      <linearGradient id="kwDocGrad" x1="0" y1="0" x2="0" y2="1">
        <stop offset="0%" stopColor="#FDFDFE" /><stop offset="100%" stopColor="#E0E0E6" />
      </linearGradient>
      <linearGradient id="kwCardGrad" x1="0" y1="0" x2="0" y2="1">
        <stop offset="0%" stopColor="#FFFFFF" /><stop offset="100%" stopColor="#E7E7EC" />
      </linearGradient>
    </defs>
    {}
    <ellipse cx="124" cy="166" rx="84" ry="13" fill="#1A1410" opacity="0.06" />
    {}
    <g transform="rotate(-7 92 84)">
      <rect x="42" y="26" width="100" height="128" rx="11" fill="url(#kwDocGrad)" stroke="#D4D4DB" strokeWidth="1.5" />
      <circle cx="92" cy="78" r="29" fill="none" stroke="#B9B9C2" strokeWidth="3" />
      <ellipse cx="92" cy="78" rx="12.5" ry="29" fill="none" stroke="#B9B9C2" strokeWidth="2.4" />
      <line x1="63" y1="78" x2="121" y2="78" stroke="#B9B9C2" strokeWidth="2.4" />
      <path d="M67 63 H117 M67 93 H117" stroke="#B9B9C2" strokeWidth="2.2" />
    </g>
    {}
    <g transform="rotate(9 168 122)">
      <rect x="120" y="88" width="106" height="68" rx="9" fill="url(#kwCardGrad)" stroke="#DBDBE1" strokeWidth="1.5" />
      <rect x="132" y="102" width="34" height="40" rx="5" fill="#ECECF0" stroke="#D0D0D7" strokeWidth="1.3" />
      <circle cx="149" cy="117" r="6.5" fill="#B9B9C2" />
      <path d="M139.5 136 a9.5 8.5 0 0 1 19 0 Z" fill="#B9B9C2" />
      <rect x="176" y="106" width="38" height="7" rx="3.5" fill="#C8C8D0" />
      <rect x="176" y="119" width="32" height="7" rx="3.5" fill="#D4D4DB" />
      <rect x="176" y="132" width="26" height="7" rx="3.5" fill="#DDDDE3" />
    </g>
  </svg>;

export const UpholdLogo = () => <div style={{
  display: "flex",
  alignItems: "center",
  gap: "0.5rem"
}}>
    <svg viewBox="0 0 14 18" style={{
  width: 30,
  height: 39
}} fill="none" xmlns="http://www.w3.org/2000/svg">
      <path fill="#35B13D" fillRule="evenodd" clipRule="evenodd" d="M11.622 9.986a9.52 9.52 0 0 1-1.536 2.343c.427-1.588.221-3.64-.702-5.631a9.941 9.941 0 0 0-1.866-2.741c1.163-.89 2.373-1.181 3.308-.771.6.262 1.062.8 1.337 1.555.521 1.43.319 3.39-.541 5.245Zm-9.744 0C1.018 8.131.815 6.17 1.337 4.741c.275-.755.737-1.293 1.337-1.555.935-.41 2.145-.12 3.308.77a9.924 9.924 0 0 0-1.866 2.742c-.924 1.992-1.13 4.043-.703 5.631a9.506 9.506 0 0 1-1.535-2.343Zm5.744 4.02c-.269.117-.562.178-.872.182a2.224 2.224 0 0 1-.872-.183c-1.801-.789-2.165-3.95-.796-6.905A8.948 8.948 0 0 1 6.75 4.642 8.926 8.926 0 0 1 8.417 7.1c1.37 2.953 1.006 6.115-.795 6.904Zm2.445-11.999C9 1.965 7.837 2.397 6.75 3.261 5.663 2.398 4.5 1.964 3.433 2.006a5.903 5.903 0 0 1 3.316-1.005c1.226 0 2.377.367 3.318 1.006Zm3.098 2.42v-.003l-.003-.006a.02.02 0 0 1-.001-.005l-.004-.01C12.255 1.77 9.684 0 6.749 0 3.807 0 1.23 1.778.334 4.424c-.001.004-.001.009-.003.013-.595 1.66-.38 3.882.58 5.952C2.226 13.223 4.61 15.19 6.72 15.19h.06c2.11 0 4.495-1.968 5.808-4.8.962-2.075 1.177-4.302.577-5.963Zm-4.61 12.321a6.517 6.517 0 0 1-1.757.25h-.084a6.53 6.53 0 0 1-1.768-.253.533.533 0 0 0-.657.337.497.497 0 0 0 .356.623 7.64 7.64 0 0 0 2.07.295h.083c.674 0 1.367-.098 2.056-.291a.497.497 0 0 0 .357-.623.533.533 0 0 0-.656-.338Z" />
    </svg>
    <span style={{
  fontWeight: 700,
  fontSize: "2.05rem",
  lineHeight: 1,
  color: "#35B13D",
  letterSpacing: "-0.03em"
}}>uphold</span>
  </div>;

export const IcoXCircle = () => <svg className="w-[22px] h-[22px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
    <circle cx="12" cy="12" r="9" /><path d="M9 9l6 6M15 9l-6 6" />
  </svg>;

export const IcoCheckCircle = () => <svg className="w-[22px] h-[22px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
    <circle cx="12" cy="12" r="9" />
    <polyline points="8.5 12 11 14.5 15.5 9.5" />
  </svg>;

export const IcoGlobe = () => <svg className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
    <circle cx="12" cy="12" r="9" /><line x1="3" y1="12" x2="21" y2="12" />
    <ellipse cx="12" cy="12" rx="4" ry="9" />
  </svg>;

export const IcoClose = () => <svg className="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
    <path d="M6 6l12 12M18 6L6 18" />
  </svg>;

export const IcoChevronDown = () => <svg className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
    <polyline points="6 9 12 15 18 9" />
  </svg>;

export const IcoChevron = () => <svg className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
    <polyline points="9 6 15 12 9 18" />
  </svg>;

export const IcoUpload = () => <svg className="w-6 h-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
    <path d="M12 16V4" /><polyline points="7 9 12 4 17 9" /><path d="M4 17v2a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-2" />
  </svg>;

export const IcoCamera = () => <svg className="w-6 h-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
    <path d="M3 8.5A2 2 0 0 1 5 6.5h2l1.5-2h7L18 6.5h1a2 2 0 0 1 2 2V18a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
    <circle cx="12" cy="13" r="3.5" />
  </svg>;

export const IcoDoc = () => <svg className="w-[22px] h-[22px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
    <path d="M6 2.5h7l5 5V21a.5.5 0 0 1-.5.5h-11A.5.5 0 0 1 6 21z" /><path d="M13 2.5V8h5" />
    <line x1="9" y1="13" x2="15" y2="13" /><line x1="9" y1="16.5" x2="15" y2="16.5" />
  </svg>;

export const IcoId = () => <svg className="w-[22px] h-[22px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
    <rect x="2.5" y="5" width="19" height="14" rx="2.5" /><circle cx="8" cy="12" r="2.4" />
    <line x1="13" y1="10.5" x2="18.5" y2="10.5" /><line x1="13" y1="14" x2="17" y2="14" />
  </svg>;

export const IcoUser = () => <svg className="w-[22px] h-[22px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
    <circle cx="12" cy="8" r="4" /><path d="M4 21a8 8 0 0 1 16 0" />
  </svg>;

export const IcoClock = () => <svg className="w-[26px] h-[26px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
    <circle cx="12" cy="12" r="9" /><polyline points="12 7 12 12 15.5 14" />
  </svg>;

export const IcoLock = () => <svg className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
    <rect x="4" y="10" width="16" height="10" rx="2.5" /><path d="M8 10V7a4 4 0 0 1 8 0v3" />
  </svg>;

export const IcoShield = () => <svg className="w-[26px] h-[26px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
    <path d="M12 3l7 3v5c0 4.4-3 8-7 9-4-1-7-4.6-7-9V6l7-3z" />
    <path d="M9 12l2 2 4-4" />
  </svg>;

export const IcoCheckSm = () => <svg className="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round">
    <polyline points="20 6 9 17 4 12" />
  </svg>;

export const IcoCheck = () => <svg className="w-7 h-7" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
    <polyline points="20 6 9 17 4 12" />
  </svg>;

export const IcoArrow = () => <svg className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
    <line x1="5" y1="12" x2="19" y2="12" /><polyline points="12 5 19 12 12 19" />
  </svg>;

export const IcoBack = () => <svg className="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
    <polyline points="15 18 9 12 15 6" />
  </svg>;

The KYC Widget is a fully Uphold-managed, embeddable solution for collecting KYC data from individual users across web and native apps. Instead of building and maintaining a custom verification interface, you embed the Widget and Uphold handles forms, document uploads, and process state on your behalf. It's fully customizable — themes, fonts, and brand colors — so it can match your app's look and feel.

<KycWidgetDemoMintlify />

***

## Features

<CardGroup cols={2}>
  <Card title="Turnkey experience" icon="key">
    Fully managed UI and verification logic with automated state handling.

    Go live quickly with minimal frontend effort.
  </Card>

  <Card title="Flexible process selection" icon="sliders">
    Run one or more KYC processes in a single flow.

    Control which processes users go through via the SDK configuration.
  </Card>

  <Card title="Multi-platform embedding" icon="mobile-screen-button">
    Embed seamlessly into web apps via iframe and native apps via WebView.

    Consistent user experience across all platforms.
  </Card>

  <Card title="Real-time event handling" icon="bolt">
    SDK emits lifecycle events such as completion, error, and cancellation.

    Integrate deeply with your app's flow and UI feedback.
  </Card>
</CardGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Installation & setup" icon="wrench" href="/widgets/kyc/installation-and-setup">
    Install the SDK, configure CSP, and set up native app integration.
  </Card>

  <Card title="User onboarding via KYC Widget" icon="user" href="/developer-guides/user-onboarding/individual/via-kyc-widget">
    End-to-end walkthrough for onboarding individual users with the Widget.
  </Card>

  <Card title="SDK reference" icon="book" href="/widgets/kyc/sdk-reference">
    Full reference for the `KycWidget` class, options, methods, and events.
  </Card>
</CardGroup>
