/* flow3.jsx — Plaid link sheet · Funding · External accounts · Agent · Off to work. */

/* =============================================================
   Plaid link — the account-linking product experience, reused for
   the funding source (one depository) and read-only externals (many).
   ============================================================= */
const BANKS = [
  { id: "chase",    name: "Chase",            tint: "#1059a8", accts: [["Checking", "Checking", "••8841", 14231], ["Brokerage", "Brokerage", "••2207", 8400]] },
  { id: "bofa",     name: "Bank of America",  tint: "#c4112f", accts: [["Advantage Checking", "Checking", "••3392", 5210], ["Rewards Savings", "Savings", "••7715", 19800]] },
  { id: "wells",    name: "Wells Fargo",      tint: "#b81e26", accts: [["Everyday Checking", "Checking", "••4471", 3120]] },
  { id: "amex",     name: "American Express",  tint: "#1b6fb3", accts: [["Platinum Card", "Card", "••1008", -2104], ["High Yield Savings", "Savings", "••9920", 22500]] },
  { id: "capone",   name: "Capital One",      tint: "#13415f", accts: [["360 Checking", "Checking", "••5567", 2840]] },
  { id: "schwab",   name: "Charles Schwab",   tint: "#00a0df", accts: [["Brokerage", "Brokerage", "••2231", 88402]] },
  { id: "fidelity", name: "Fidelity",         tint: "#3a8c3f", accts: [["Individual", "Brokerage", "••6610", 31980]] },
  { id: "coinbase", name: "Coinbase",         tint: "#1652f0", accts: [["Portfolio", "Crypto", "••4417", 6712]] },
];

/* Plaid link. `requireFunding` (no funding source established yet) forces the
   user to include a checking/savings account in their selection — so every
   exit from Plaid leaves them with a usable funding source. Always
   multi-select: you link a bank and pull along any other accounts at once. */
const PlaidLink = ({ mode, requireFunding = false, onClose, onLinked, initialStep, initialBankId, initialSel }) => {
  // step: "list" | "connecting" | "select"
  const [step, setStep] = useState(initialStep || "list");
  const [bank, setBank] = useState(() => initialBankId ? BANKS.find((b) => b.id === initialBankId) || null : null);
  const [q, setQ] = useState("");
  const [sel, setSel] = useState(() => new Set(initialSel || []));

  // When establishing the funding source, only surface institutions that
  // actually have a depository account to link.
  const pool = requireFunding ? BANKS.filter((b) => b.accts.some((a) => a[1] === "Checking" || a[1] === "Savings")) : BANKS;
  const shown = pool.filter((b) => b.name.toLowerCase().includes(q.trim().toLowerCase()));

  const isDep = (a) => a[1] === "Checking" || a[1] === "Savings";

  const pick = (b) => {
    setBank(b); setStep("connecting");
    // pre-select every account at the institution — the user trims from there
    setSel(new Set(b.accts.map((_, i) => i)));
    setTimeout(() => setStep("select"), 1700);
  };
  const toggle = (i) => setSel((prev) => { const n = new Set(prev); n.has(i) ? n.delete(i) : n.add(i); return n; });

  // the funding source = first selected depository at this institution
  const fundingIdx = bank ? bank.accts.findIndex((a, i) => sel.has(i) && isDep(a)) : -1;
  const needsFunding = requireFunding && fundingIdx < 0;

  const finish = () => {
    const accts = [...sel].map((i) => ({ inst: bank.name, instId: bank.id, tint: bank.tint, name: bank.accts[i][0], type: bank.accts[i][1], mask: bank.accts[i][2], bal: bank.accts[i][3] }));
    onLinked(accts);
  };

  return (
    <div className="yo-enter" style={{ position: "absolute", inset: 0, zIndex: 410, background: "#f6f7f9", display: "flex", flexDirection: "column" }}>
      <div style={{ flex: "none", display: "flex", alignItems: "center", padding: "52px 18px 12px", gap: 10 }}>
        <button className="press" onClick={step === "list" ? onClose : () => setStep("list")} aria-label="Back" style={{ background: "none", border: "none", padding: 4, margin: "0 -4px", color: "#15171a", display: "flex" }}>
          <Icon name={step === "list" ? "close" : "back"} size={22} color="#15171a" />
        </button>
        <div style={{ flex: 1, display: "flex", justifyContent: "center" }}><PlaidMark /></div>
        <span style={{ width: 22 }} />
      </div>

      {step === "list" && (
        <>
          <div style={{ flex: "none", padding: "6px 22px 14px" }}>
            <PHead>{mode === "funding" ? "Select your bank" : "Select an institution"}</PHead>
            <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "13px 14px", background: "#fff", border: "1.5px solid #d8dadf", borderRadius: 12, marginTop: 16 }}>
              <Icon name="search" size={17} color="#9a9ea6" />
              <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search 12,000+ institutions" autoFocus
                style={{ flex: 1, border: "none", outline: "none", background: "transparent", fontSize: 15, color: "#1a1c1f" }} />
            </div>
          </div>
          <div className="scroll" style={{ flex: 1, minHeight: 0, padding: "0 22px 16px" }}>
            {shown.map((b) => (
              <button key={b.id} className="press" onClick={() => pick(b)} style={{ width: "100%", display: "flex", alignItems: "center", gap: 13, padding: "14px 4px", background: "none", border: "none", borderBottom: "1px solid #eceef1", cursor: "pointer", textAlign: "left" }}>
                <span style={{ width: 38, height: 38, flex: "none", borderRadius: 9, background: b.tint, display: "grid", placeItems: "center", color: "#fff", fontFamily: "var(--f-display)", fontSize: 17, fontWeight: 700 }}>{b.name[0]}</span>
                <span style={{ flex: 1, fontFamily: "var(--f-display)", fontSize: 15.5, fontWeight: 600, color: "#1a1c1f" }}>{b.name}</span>
                <Icon name="arrow" size={17} color="#b6b9bf" />
              </button>
            ))}
          </div>
        </>
      )}

      {step === "connecting" && (
        <div style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", padding: "0 30px", textAlign: "center" }}>
          <span style={{ width: 64, height: 64, borderRadius: 14, background: bank.tint, display: "grid", placeItems: "center", color: "#fff", fontFamily: "var(--f-display)", fontSize: 28, fontWeight: 700 }}>{bank.name[0]}</span>
          <div style={{ marginTop: 22, display: "flex", alignItems: "center", gap: 8, color: "#15171a" }}>
            <LiveDot size={6} color="#111" />
            <span style={{ fontFamily: "var(--f-display)", fontSize: 16, fontWeight: 600 }}>Connecting to {bank.name}…</span>
          </div>
          <div style={{ fontFamily: "var(--f-display)", fontSize: 13, color: "#6b6f76", marginTop: 10, lineHeight: 1.5, maxWidth: "28ch" }}>
            Plaid signs you in securely. Yoshi never sees your bank password.
          </div>
        </div>
      )}

      {step === "select" && (
        <>
          <div className="scroll" style={{ flex: 1, minHeight: 0, padding: "6px 22px 8px" }}>
            <PHead>Accounts at {bank.name}</PHead>
            <PNote>{requireFunding ? "Pick a checking or savings account to fund Yoshi. Add any others for Yoshi to read." : "Select which accounts Yoshi can see. Add a checking or savings to move money."}</PNote>
            <div style={{ marginTop: 18, display: "grid", gap: 10 }}>
              {bank.accts.map((a, i) => {
                const on = sel.has(i);
                const isFunding = i === fundingIdx;
                return (
                  <button key={i} className="press" onClick={() => toggle(i)} style={{ width: "100%", textAlign: "left", display: "flex", alignItems: "center", gap: 13, padding: "14px 15px", background: "#fff", border: `1.5px solid ${on ? "#111" : "#e1e3e8"}`, borderRadius: 12, cursor: "pointer" }}>
                    <span style={{ flex: 1, minWidth: 0 }}>
                      <span style={{ display: "flex", alignItems: "center", gap: 7 }}>
                        <span style={{ fontFamily: "var(--f-display)", fontSize: 15, fontWeight: 600, color: "#1a1c1f" }}>{a[0]}</span>
                      </span>
                      <span style={{ display: "block", fontFamily: "var(--f-display)", fontSize: 12.5, color: "#8a8e96", marginTop: 2 }}>{a[1]} · {a[2]}</span>
                    </span>
                    <span style={{ fontFamily: "var(--f-mono)", fontSize: 14, fontWeight: 600, color: a[3] < 0 ? "#b03a2e" : "#1a1c1f" }}>{a[3] < 0 ? "−$" : "$"}{Math.abs(a[3]).toLocaleString("en-US")}</span>
                    <span style={{ width: 22, height: 22, flex: "none", borderRadius: 6, border: `1.5px solid ${on ? "#111" : "#cdd0d5"}`, background: on ? "#111" : "transparent", display: "grid", placeItems: "center" }}>
                      {on && <Icon name="check" size={13} stroke={2.4} color="#fff" />}
                    </span>
                  </button>
                );
              })}
            </div>
            {needsFunding && (
              <div style={{ display: "flex", alignItems: "flex-start", gap: 8, marginTop: 14, padding: "11px 13px", background: "#fcf3e6", border: "1px solid #e7c98f", borderRadius: 10 }}>
                <span style={{ flex: "none", marginTop: 1, color: "#9a6a14" }}><Icon name="bank" size={15} color="#9a6a14" /></span>
                <span style={{ fontFamily: "var(--f-display)", fontSize: 12.5, color: "#7a5410", lineHeight: 1.45 }}>Select a checking or savings account to fund Yoshi.</span>
              </div>
            )}
          </div>
          <div style={{ flex: "none", padding: "12px 22px 26px" }}>
            <PBtn disabled={sel.size === 0} onClick={finish}>{`Link ${sel.size} account${sel.size === 1 ? "" : "s"}`}</PBtn>
            <div style={{ display: "flex", alignItems: "center", justifyContent: "center", gap: 6, marginTop: 14, color: "#9a9ea6" }}>
              <Icon name="shield" size={13} color="#9a9ea6" />
              <span style={{ fontFamily: "var(--f-display)", fontSize: 11, fontWeight: 600 }}>Secured by Plaid</span>
            </div>
          </div>
        </>
      )}
    </div>
  );
};

/* =============================================================
   08 · CONNECT YOUR BANK — link once through Plaid; it pulls every
   account at that institution. Pick the one that funds Yoshi (read/write);
   the rest ride along read-only. The more you connect, the more Yoshi sees.
   ============================================================= */
const FUND_PRESETS = [250, 1000, 5000, 10000];

/* What Yoshi can do once it can SEE a given institution — the concrete
   payoff for connecting more, surfaced live as accounts come in. */
const INSIGHTS = {
  amex:     { tag: "Pay down your card", find: "Your Amex balance is accruing interest at 21.99% APR. Yoshi can clear it from cash before it's due.", value: "Stops interest", w: 95 },
  schwab:   { tag: "Put idle cash to work", find: "Uninvested cash is sitting in your Schwab brokerage. Yoshi can invest it on a schedule.", value: "+$1,240 / yr", w: 82 },
  fidelity: { tag: "Fix portfolio drift", find: "Your Fidelity mix has drifted from target after the run-up. Yoshi can propose a rebalance.", value: "Back on target", w: 78 },
  chase:    { tag: "Sweep idle cash", find: "Cash is sitting in Chase earning almost nothing. Yoshi can sweep it to 4.8% APY.", value: "+$402 / yr", w: 70 },
  bofa:     { tag: "Sweep idle cash", find: "Idle cash in Bank of America could earn 4.8% instead of sitting still.", value: "+$360 / yr", w: 68 },
  coinbase: { tag: "One net worth", find: "Your Coinbase crypto now rolls into a single balance Yoshi watches with everything else.", value: "Tracked", w: 45 },
  wells:    { tag: "Catch recurring fees", find: "With Wells Fargo visible, Yoshi can flag recurring fees and forgotten subscriptions.", value: "Watching", w: 35 },
  capone:   { tag: "Catch recurring fees", find: "Capital One spending is now visible. Yoshi spots fees and duplicate subscriptions.", value: "Watching", w: 34 },
};

const isDepository = (a) => a.type === "Checking" || a.type === "Savings";
const acctLabel = (a) => `${a.inst} ${a.type} · ${a.mask}`;
const sameAcct = (a, b) => !!(a && b && a.instId === b.instId && a.mask === b.mask);

/* ---- Connected account row ---- */
const ConnectedRow = ({ a, selected, onSelect, accent }) => (
  <div className="yo-enter" style={{ display: "flex", alignItems: "center", gap: 13, padding: "13px 14px", background: "var(--bg-card)", border: `1px solid ${accent ? "var(--accent)" : "var(--rule-2)"}`, borderRadius: 12 }}>
    <span style={{ width: 34, height: 34, flex: "none", borderRadius: 8, background: a.tint, display: "grid", placeItems: "center", color: "#fff", fontFamily: "var(--f-display)", fontSize: 15, fontWeight: 700 }}>{a.inst[0]}</span>
    <div style={{ flex: 1, minWidth: 0 }}>
      <div style={{ fontFamily: "var(--f-display)", fontSize: 14, fontWeight: 600 }}>{a.inst} {a.type}</div>
      <div style={{ fontFamily: "var(--f-mono)", fontSize: 10.5, color: "var(--ink-3)", letterSpacing: "0.04em", marginTop: 2 }}>{a.mask}</div>
    </div>
    {onSelect && (
      <button onClick={onSelect} style={{ background: "none", border: "none", padding: 4, cursor: "pointer", color: selected ? "var(--accent)" : "var(--ink-3)" }}>
        <Icon name="check" size={16} stroke={selected ? 2.4 : 1.5} color={selected ? "var(--accent)" : "var(--rule-2)"} />
      </button>
    )}
    {!onSelect && a.type !== "Checking" && a.type !== "Savings" && (
      <span style={{ display: "inline-flex", alignItems: "center", gap: 4 }}>
        <Icon name="eye" size={12} color="var(--ink-3)" />
      </span>
    )}
    {!onSelect && (a.type === "Checking" || a.type === "Savings") && (
      <span style={{ fontFamily: "var(--f-mono)", fontSize: 13, fontWeight: 600, color: "var(--ink-2)" }}>${Math.abs(a.bal).toLocaleString("en-US")}</span>
    )}
  </div>
);

const Funding = ({ funding, setFunding, externals, setExternals, onNext, onSkipToAgent }) => {
  const [plaid, setPlaid]           = useState(false);
  const [attempts, setAttempts]     = useState(0);   // how many times Plaid was opened
  const [plaidFailed, setPlaidFailed] = useState(false); // last attempt failed/exited

  const depAccts  = externals.filter(isDepository);
  const hasBank   = depAccts.length > 0;
  const hasInvest = externals.some((a) => a.type === "Brokerage" || a.type === "Crypto");
  const hasAny    = externals.length > 0;

  // state 1: bank linked → Next goes to funding page
  // state 2: invest-only → Next goes to funding page (will prompt bank link there)
  // state 3: failed/exited → Next skips to agent (no retry gating)
  const canProceed = hasAny || plaidFailed;
  const skipToAgent = !hasAny && plaidFailed;

  const onLinked = (accts) => {
    const next = [...externals];
    accts.forEach((a) => { if (!next.some((x) => sameAcct(x, a))) next.push(a); });
    setExternals(next);
    if (!funding) { const dep = next.find(isDepository); if (dep) setFunding(dep); }
    setPlaid(false);
    setPlaidFailed(false);
  };

  const onPlaidClose = () => {
    setPlaid(false);
    setPlaidFailed(true);
  };

  const openPlaid = () => {
    setAttempts((n) => n + 1);
    setPlaid(true);
  };

  // idle state: nothing linked yet, no failure
  const showIdle = !hasAny && !plaidFailed;
  // failure state: exited/errored, haven't succeeded
  const showRetry = !hasAny && plaidFailed;

  return (
    <Screen>
      <Body>
        <H>Connect your<Brk /><Accent>accounts.</Accent></H>
        <Sub>Link securely through Plaid to power Yoshi. The more accounts you connect, the more Yoshi can see and do.</Sub>

        {/* ---- IDLE: nothing linked yet ---- */}
        {showIdle && (
          <>
            <button className="press" onClick={openPlaid} style={{ width: "100%", display: "flex", alignItems: "center", gap: 13, marginTop: 18, padding: "16px 15px", background: "var(--bg-card)", border: "1px dashed var(--rule-2)", borderRadius: 12, cursor: "pointer", textAlign: "left" }}>
              <span style={{ flex: "none", color: "var(--accent)" }}><Icon name="bank" size={24} color="var(--accent)" /></span>
              <span style={{ flex: 1 }}>
                <span style={{ display: "block", fontFamily: "var(--f-display)", fontSize: 15, fontWeight: 600 }}>Link accounts</span>
              </span>
              <Icon name="arrow" size={18} color="var(--ink-3)" />
            </button>
            <Disclosure>Connections run through Plaid. Yoshi never sees your password, and every move still needs your approval.</Disclosure>
          </>
        )}

        {/* ---- RETRY: Plaid failed or exited ---- */}
        {showRetry && (
          <>
            <div style={{ marginTop: 18, padding: "13px 14px", background: "color-mix(in srgb, var(--accent) 14%, var(--bg-card))", border: "1px solid var(--accent)", borderRadius: 12 }}>
              <div style={{ display: "flex", alignItems: "flex-start", gap: 9 }}>
                <span style={{ flex: "none", marginTop: 1, color: "var(--accent)" }}><Icon name="bank" size={16} color="var(--accent)" /></span>
                <div style={{ flex: 1, fontFamily: "var(--f-display)", fontSize: 13.5, fontWeight: 600, color: "var(--ink)", lineHeight: 1.45 }}>Connection didn't complete. That's okay, try again below.</div>
              </div>
            </div>
            <button className="press" onClick={openPlaid} style={{ width: "100%", display: "flex", alignItems: "center", gap: 13, marginTop: 10, padding: "16px 15px", background: "var(--bg-card)", border: "1px dashed var(--rule-2)", borderRadius: 12, cursor: "pointer", textAlign: "left" }}>
              <span style={{ flex: "none", color: "var(--accent)" }}><Icon name="bank" size={24} color="var(--accent)" /></span>
              <span style={{ flex: 1 }}>
                <span style={{ display: "block", fontFamily: "var(--f-display)", fontSize: 15, fontWeight: 600 }}>Link accounts</span>
              </span>
              <Icon name="arrow" size={18} color="var(--ink-3)" />
            </button>
            <Disclosure>You can always connect accounts later from the Accounts tab.</Disclosure>
          </>
        )}

        {/* ---- STATE 1 + 2: Accounts linked ---- */}
        {hasAny && (
          <>
            {/* All linked accounts — bank, brokerage, crypto, side by side */}
            <SubHead>Connected accounts</SubHead>
            <div style={{ display: "grid", gap: 9 }}>
              {externals.map((a, i) => (
                <ConnectedRow key={i} a={a} accent={isDepository(a) && sameAcct(a, funding)} selected={sameAcct(a, funding)} />
              ))}
            </div>

            {/* No bank — callout */}
            {!hasBank && (
              <div style={{ marginTop: 18, padding: "13px 14px", background: "color-mix(in srgb, var(--accent) 14%, var(--bg-card))", border: "1px solid var(--accent)", borderRadius: 12 }}>
                <div style={{ display: "flex", alignItems: "flex-start", gap: 9 }}>
                  <span style={{ flex: "none", marginTop: 1, color: "var(--accent)" }}><Icon name="bank" size={16} color="var(--accent)" /></span>
                  <div style={{ flex: 1, fontFamily: "var(--f-display)", fontSize: 13.5, fontWeight: 600, color: "var(--ink)" }}>You'll need to add a checking or savings account to fund Yoshi.</div>
                </div>
              </div>
            )}
          </>
        )}
      </Body>
      <Dock>
        {hasAny ? (
          <Btn full onClick={onNext}>Continue <Icon name="arrow" size={15} color="var(--accent-ink)" /></Btn>
        ) : plaidFailed ? (
          <SkipLink onClick={onSkipToAgent}>Skip for now</SkipLink>
        ) : null}
      </Dock>
      {plaid && <PlaidLink mode="readonly" requireFunding={!funding} onClose={onPlaidClose} onLinked={onLinked} />}
    </Screen>
  );
};

/* =============================================================
   09 · PUT YOSHI TO WORK — fund the account so Yoshi has something
   to work with. Optional; skip and fund later.
   ============================================================= */
const FundDeposit = ({ funding, setFunding, externals = [], setExternals, deposit, setDeposit, onNext, onSkip }) => {
  const [amt, setAmt] = useState(deposit || 0);
  const [other, setOther] = useState(false);
  const [customStr, setCustomStr] = useState("");
  const [confirming, setConfirming] = useState(false);
  const [confirmed, setConfirmed] = useState(false);
  const [pickerOpen, setPickerOpen] = useState(false);
  const [plaid, setPlaid] = useState(false);
  const web = usePlatform() === "web";

  const banks = externals.filter(isDepository);
  const hasMultipleBanks = banks.length > 1;

  const onLinked = (accts) => {
    const next = [...externals];
    accts.forEach((a) => { if (!next.some((x) => sameAcct(x, a))) next.push(a); });
    setExternals(next);
    if (!funding) { const dep = next.find(isDepository); if (dep) setFunding(dep); }
    setPlaid(false);
  };

  const handleNext = () => {
    if (amt > 0 && !confirmed) { setConfirming(true); return; }
    setDeposit(amt); onNext();
  };

  const onPasskeyConfirm = () => {
    setConfirming(false);
    setConfirmed(true);
    setTimeout(() => { setDeposit(amt); onNext(); }, 400);
  };
  return (
    <Screen>
      <Body>
        <H>Put Yoshi<Brk />to <Accent>work.</Accent></H>
        <Sub>Move money into your Yoshi account so it has something to work with. You can skip and fund anytime later.</Sub>

        {funding && (
          <div style={{ marginTop: 20 }}>
            <button
              type="button"
              onClick={() => hasMultipleBanks && setPickerOpen((o) => !o)}
              disabled={!hasMultipleBanks}
              style={{
                width: "100%", display: "flex", alignItems: "center", gap: 12,
                padding: "13px 14px", background: "var(--bg-card)",
                border: "1px solid var(--rule-2)",
                borderRadius: pickerOpen ? "12px 12px 0 0" : 12,
                borderBottomColor: pickerOpen ? "transparent" : "var(--rule-2)",
                cursor: hasMultipleBanks ? "pointer" : "default",
                textAlign: "left",
              }}>
              <span style={{ width: 34, height: 34, flex: "none", borderRadius: 8, background: funding.tint, display: "grid", placeItems: "center", color: "#fff", fontFamily: "var(--f-display)", fontSize: 15, fontWeight: 700 }}>{funding.inst[0]}</span>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontFamily: "var(--f-display)", fontSize: 14, fontWeight: 600 }}>{funding.inst} {funding.type} <span style={{ fontFamily: "var(--f-mono)", fontSize: 11, color: "var(--ink-3)", fontWeight: 400 }}>{funding.mask}</span></div>
              </div>
              <span style={{ flex: "none", display: "inline-flex", alignItems: "center", gap: 3, fontFamily: "var(--f-mono)", fontSize: 9.5, fontWeight: 600, letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--accent)", padding: "3px 8px 3px 6px", borderRadius: 999, background: "color-mix(in srgb, var(--accent) 12%, var(--bg-card))", border: "1px solid color-mix(in srgb, var(--accent) 40%, transparent)" }}><Icon name="bolt" size={11} stroke={1.8} color="var(--accent)" />Instant</span>
              {hasMultipleBanks && (
                <Icon name={pickerOpen ? "up" : "down"} size={16} color="var(--ink-3)" />
              )}
            </button>

            {pickerOpen && hasMultipleBanks && (
              <div style={{ border: "1px solid var(--rule-2)", borderTop: "none", borderRadius: "0 0 12px 12px", background: "var(--bg-card)", overflow: "hidden" }}>
                {banks.filter((b) => !sameAcct(b, funding)).map((a, i) => (
                  <button key={i} type="button" onClick={() => { setFunding(a); setPickerOpen(false); }}
                    style={{ width: "100%", display: "flex", alignItems: "center", gap: 12, padding: "12px 14px", background: "transparent", border: "none", borderTop: "1px solid var(--rule)", cursor: "pointer", textAlign: "left" }}>
                    <span style={{ width: 30, height: 30, flex: "none", borderRadius: 8, background: a.tint, display: "grid", placeItems: "center", color: "#fff", fontFamily: "var(--f-display)", fontSize: 13, fontWeight: 700 }}>{a.inst[0]}</span>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontFamily: "var(--f-display)", fontSize: 13.5, fontWeight: 500 }}>{a.inst} {a.type} <span style={{ fontFamily: "var(--f-mono)", fontSize: 10.5, color: "var(--ink-3)", fontWeight: 400 }}>{a.mask}</span></div>
                    </div>
                  </button>
                ))}
              </div>
            )}
          </div>
        )}

        {!funding && (
          <>
            <div style={{ marginTop: 20, padding: "13px 14px", background: "color-mix(in srgb, var(--accent) 14%, var(--bg-card))", border: "1px solid var(--accent)", borderRadius: 12 }}>
              <div style={{ display: "flex", alignItems: "flex-start", gap: 9 }}>
                <span style={{ flex: "none", marginTop: 1, color: "var(--accent)" }}><Icon name="bank" size={16} color="var(--accent)" /></span>
                <div style={{ flex: 1 }}>
                  <div style={{ fontFamily: "var(--f-display)", fontSize: 13.5, fontWeight: 600, color: "var(--ink)" }}>You'll need to add a checking or savings account to fund Yoshi</div>
                </div>
              </div>
            </div>
            <button className="press" onClick={() => setPlaid(true)} style={{ width: "100%", display: "flex", alignItems: "center", gap: 13, marginTop: 10, padding: "14px 15px", background: "var(--bg-card)", border: "1px dashed var(--rule-2)", borderRadius: 12, cursor: "pointer", textAlign: "left" }}>
              <span style={{ flex: "none", color: "var(--accent)" }}><Icon name="bank" size={22} color="var(--accent)" /></span>
              <span style={{ flex: 1, fontFamily: "var(--f-display)", fontSize: 14.5, fontWeight: 600 }}>Link bank account</span>
              <Icon name="arrow" size={18} color="var(--ink-3)" />
            </button>
          </>
        )}

        <SubHead>Amount <span style={{ fontWeight: 500, letterSpacing: 0, textTransform: "none", color: "var(--ink-3)" }}>· optional</span></SubHead>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 7, opacity: funding ? 1 : 0.45, pointerEvents: funding ? "auto" : "none" }}>
          {FUND_PRESETS.map((p) => {
            const on = !other && amt === p;
            return (
              <button key={p} className="press" disabled={!funding} onClick={() => { setOther(false); setAmt(on ? 0 : p); }} style={{ padding: "13px 2px", cursor: funding ? "pointer" : "not-allowed", borderRadius: 10, background: on ? "color-mix(in srgb, var(--accent) 12%, var(--bg-card))" : "var(--bg-2)", border: `1px solid ${on ? "var(--accent)" : "var(--rule)"}`, fontFamily: "var(--f-display)", fontSize: 12.5, fontWeight: 700, color: "var(--ink)" }}>
                ${p >= 1000 ? `${p / 1000}k` : p}
              </button>
            );
          })}
          <button className="press" disabled={!funding} onClick={() => { setOther(true); setAmt(customStr ? parseInt(customStr, 10) : 0); }} style={{ padding: "13px 2px", cursor: funding ? "pointer" : "not-allowed", borderRadius: 10, background: other ? "color-mix(in srgb, var(--accent) 12%, var(--bg-card))" : "var(--bg-2)", border: `1px solid ${other ? "var(--accent)" : "var(--rule)"}`, fontFamily: "var(--f-display)", fontSize: 12.5, fontWeight: 700, color: "var(--ink)" }}>
            Other
          </button>
        </div>
        {funding && other && (
          <div className="yo-enter" style={{ marginTop: 9 }}>
            <Field prefix="$" inputMode="numeric" autoFocus placeholder="Enter an amount"
              value={customStr ? parseInt(customStr, 10).toLocaleString("en-US") : ""}
              onChange={(v) => { const d = v.replace(/[^0-9]/g, ""); setCustomStr(d); setAmt(d ? parseInt(d, 10) : 0); }} />
          </div>
        )}

        <Disclosure>Funds at Yoshi are FDIC-insured up to $250,000 through our partner banks. Every move still needs your approval.</Disclosure>

      </Body>
      <Dock>
        <Btn full disabled={!funding || amt <= 0} onClick={handleNext}>
          {confirmed ? <><Icon name="check" size={18} color="var(--accent-ink)" /> Confirmed</> : <>Confirm with passkey <Icon name="shield" size={18} color={(!funding || amt <= 0) ? "var(--ink-3)" : "var(--accent-ink)"} /></>}
        </Btn>
        <SkipLink onClick={onSkip}>Skip for now</SkipLink>
      </Dock>

      {/* Passkey confirm — centered modal on web, bottom sheet on mobile */}
      {confirming && (
        <>
          <div onClick={() => setConfirming(false)} style={{ position: "absolute", inset: 0, zIndex: 50, background: "rgba(0,0,0,0.44)", backdropFilter: "blur(4px)", WebkitBackdropFilter: "blur(4px)" }} />
          {web ? (
            <div style={{ position: "absolute", inset: 0, zIndex: 51, display: "flex", alignItems: "center", justifyContent: "center", padding: 28 }}>
              <div className="yo-enter" style={{ width: "100%", maxWidth: 360, background: "var(--bg-card)", border: "1px solid var(--rule-2)", borderRadius: 16, padding: "30px 28px 26px", boxShadow: "0 16px 40px -16px rgba(0,0,0,0.34)" }}>
                <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 10, marginBottom: 24 }}>
                  <span style={{ width: 52, height: 52, borderRadius: 14, background: "var(--bg-2)", border: "1px solid var(--rule-2)", display: "grid", placeItems: "center" }}>
                    <Icon name="shield" size={26} color="var(--accent)" />
                  </span>
                  <div style={{ textAlign: "center" }}>
                    <div style={{ fontFamily: "var(--f-display)", fontSize: 17, fontWeight: 700, letterSpacing: "-0.02em" }}>Confirm with passkey</div>
                    <div style={{ fontFamily: "var(--f-display)", fontSize: 13, color: "var(--ink-3)", marginTop: 5, lineHeight: 1.45 }}>
                      Authorise a transfer of <strong>${amt.toLocaleString("en-US")}</strong> from your {funding ? `${funding.inst} ${funding.type}` : "funding source"}.
                    </div>
                  </div>
                </div>
                <div style={{ display: "grid", gap: 9 }}>
                  <Btn full onClick={onPasskeyConfirm}>
                    <Icon name="shield" size={16} color="var(--accent-ink)" /> Use passkey
                  </Btn>
                  <button onClick={() => setConfirming(false)} style={{ background: "none", border: "none", fontFamily: "var(--f-display)", fontSize: 14, color: "var(--ink-3)", cursor: "pointer", padding: "8px 0" }}>Cancel</button>
                </div>
              </div>
            </div>
          ) : (
            <div style={{ position: "absolute", bottom: 0, left: 0, right: 0, zIndex: 51, background: "var(--bg-card)", borderRadius: "20px 20px 0 0", padding: "20px 24px 40px", boxShadow: "0 -8px 32px rgba(0,0,0,0.18)" }}>
              <div style={{ width: 36, height: 4, borderRadius: 999, background: "var(--rule-2)", margin: "0 auto 22px" }} />
              <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 10, marginBottom: 24 }}>
                <span style={{ width: 52, height: 52, borderRadius: 14, background: "var(--bg-2)", border: "1px solid var(--rule-2)", display: "grid", placeItems: "center" }}>
                  <Icon name="shield" size={26} color="var(--accent)" />
                </span>
                <div style={{ textAlign: "center" }}>
                  <div style={{ fontFamily: "var(--f-display)", fontSize: 17, fontWeight: 700, letterSpacing: "-0.02em" }}>Confirm with passkey</div>
                  <div style={{ fontFamily: "var(--f-display)", fontSize: 13, color: "var(--ink-3)", marginTop: 5, lineHeight: 1.45 }}>
                    Authorise a transfer of <strong>${amt.toLocaleString("en-US")}</strong> from your {funding ? `${funding.inst} ${funding.type}` : "funding source"}.
                  </div>
                </div>
              </div>
              <div style={{ display: "grid", gap: 9 }}>
                <Btn full onClick={onPasskeyConfirm}>
                  <Icon name="shield" size={16} color="var(--accent-ink)" /> Use passkey
                </Btn>
                <button onClick={() => setConfirming(false)} style={{ background: "none", border: "none", fontFamily: "var(--f-display)", fontSize: 14, color: "var(--ink-3)", cursor: "pointer", padding: "8px 0" }}>Cancel</button>
              </div>
            </div>
          )}
        </>
      )}
      {plaid && <PlaidLink mode="readonly" requireFunding onClose={() => setPlaid(false)} onLinked={onLinked} />}
    </Screen>
  );
};

/* =============================================================
   10 · AGENT — connect an assistant (kept as-is)
   ============================================================= */
const AGENTS = [
  /* Yoshi's own integration methods */
  { id: "mcp",        name: "Yoshi MCP",         icon: "connect",  kind: "copy" },
  { id: "build",      name: "Build with Yoshi",  icon: "easel",    kind: "copy" },
  { id: "sdks",       name: "Yoshi SDKs",        icon: "terminal", kind: "sdk" },
  /* apps you authorize over OAuth */
  { id: "chatgpt",    name: "ChatGPT",           icon: "message",  kind: "oauth" },
  { id: "claude",     name: "Claude",            icon: "robot",    kind: "oauth" },
  { id: "perplexity", name: "Perplexity",        icon: "search",   kind: "oauth" },
  { id: "cursor",     name: "Cursor",            icon: "terminal", kind: "oauth" },
  { id: "openclaw",   name: "OpenClaw",          icon: "bolt",     kind: "copy" },
];

const AGENT_SETUP = {
  mcp:      "yoshi mcp add --key ys_demo_8f3ac2d1",
  build:    "npm i @yoshi/sdk && yoshi init",
  openclaw: "openclaw connect yoshi --key ys_demo_8f3ac2d1",
};

/* one marketplace card — icon, name, and a state-driven footer action */
const AgentCard = ({ a, state, open, onClick }) => {
  const web = usePlatform() === "web";
  const active = state === "activated" || state === "live" || state === "connected";
  const statusLabel = state === "live" ? "Live" : state === "connected" ? "Connected" : "Activated";
  const btnLabel = state === "copy" ? "Copy setup" : "Authorize";
  return (
    <button key={a.id} className="press" onClick={onClick} style={{ position: "relative", textAlign: "left", cursor: "pointer", padding: web ? "12px 13px 11px" : "16px 15px 14px", borderRadius: 12, background: "var(--bg-card)", border: `1px solid ${active || open ? "var(--accent)" : "var(--rule)"}`, color: "var(--ink)", display: "flex", flexDirection: "column", gap: web ? 8 : 11, minHeight: web ? 116 : 152, overflow: "hidden" }}>
      {active && <span style={{ position: "absolute", top: 0, left: 0, right: 0, height: 2, background: "var(--accent)" }} />}
      <span style={{ width: web ? 32 : 38, height: web ? 32 : 38, flex: "none", border: `1px solid ${active ? "var(--accent)" : "var(--rule-2)"}`, borderRadius: 9, display: "grid", placeItems: "center", color: active ? "var(--accent)" : "var(--ink-2)" }}>
        <Icon name={a.icon} size={web ? 17 : 19} stroke={1.6} color={active ? "var(--accent)" : "var(--ink-2)"} />
      </span>
      <div style={{ fontFamily: "var(--f-display)", fontSize: web ? 14.5 : 15.5, fontWeight: 700, letterSpacing: "-0.015em", textWrap: "pretty", lineHeight: 1.2 }}>{a.name}</div>
      <div style={{ marginTop: "auto", width: "100%" }}>
        {active ? (
          <span style={{ display: "inline-flex", alignItems: "center", gap: 7, fontFamily: "var(--f-display)", fontSize: 12.5, fontWeight: 600, color: "var(--accent)" }}>
            <span style={{ width: 6, height: 6, borderRadius: 999, background: "var(--accent)" }} /> {statusLabel}
          </span>
        ) : state === "sdk" ? (
          <span style={{ display: "flex", alignItems: "center", justifyContent: "space-between", fontFamily: "var(--f-display)", fontSize: 13, fontWeight: 600, color: "var(--accent)" }}>
            View SDKs <Icon name="back" size={14} color="var(--accent)" style={{ transform: "scaleX(-1)" }} />
          </span>
        ) : (
          <span style={{ display: "block", textAlign: "center", padding: "9px 0", borderRadius: 8, background: "var(--bg-2)", border: "1px solid var(--rule-2)", fontFamily: "var(--f-display)", fontSize: 13, fontWeight: 600, color: "var(--ink)" }}>{btnLabel}</span>
        )}
      </div>
    </button>
  );
};

const Agent = ({ agents = [], setAgents, onNext, onSkip }) => {
  const [redirecting, setRedirecting] = useState(null); // OAuth agent id mid-authorize
  const [setupId, setSetupId] = useState(null);         // copy-agent id whose command is shown
  const [copied, setCopied] = useState(false);
  const web = usePlatform() === "web";
  const isConnected = (id) => agents.includes(id);
  const markConnected = (id) => setAgents((prev) => (prev.includes(id) ? prev : [...prev, id]));
  const cardState = (a) => {
    if (a.kind === "sdk") return "sdk";
    if (a.kind === "copy") return isConnected(a.id) ? "connected" : "copy";
    return isConnected(a.id) ? "activated" : "authorize";
  };

  const connect = (a) => {
    if (a.kind === "sdk") return;
    if (isConnected(a.id)) {                              // tap connected → disconnect
      setAgents(agents.filter((x) => x !== a.id));
      if (setupId === a.id) setSetupId(null);
      return;
    }
    if (a.kind === "copy") {                              // MCP / CLI → reveal command to run
      setCopied(false);
      setSetupId((cur) => (cur === a.id ? null : a.id));
      return;
    }
    setRedirecting(a.id);                                 // OAuth agent → leave & return
    setTimeout(() => { markConnected(a.id); setRedirecting(null); }, 1700);
  };

  const doCopy = () => {
    try { navigator.clipboard && navigator.clipboard.writeText(AGENT_SETUP[setupId] || ""); } catch (e) {}
    setCopied(true);
    markConnected(setupId);
  };

  const redirectAgent = AGENTS.find((a) => a.id === redirecting);
  const setupAgent = AGENTS.find((a) => a.id === setupId);
  const count = agents.length;

  return (
  <Screen style={{ position: "relative" }}>
    <Body>
      <H>Bring your AI<Brk />into the <Accent>loop.</Accent></H>
      <Sub>Connect the assistants you already use and they can draft moves right in your chats. You still approve every one.</Sub>

      <div style={{ display: "grid", gridTemplateColumns: web ? "repeat(3, 1fr)" : "repeat(2, 1fr)", gap: 11, marginTop: 20 }}>
        {AGENTS.map((a) => {
          const st = cardState(a);
          const open = setupId === a.id && st === "copy";
          return <AgentCard key={a.id} a={a} state={st} open={open} onClick={() => connect(a)} />;
        })}
      </div>

      {/* CLI agents — copy the command, run it in your own agent framework to connect */}
      {setupAgent && !isConnected(setupAgent.id) && (
        <div className="yo-enter" style={{ marginTop: 12 }}>
          <div style={{ display: "flex", gap: 10, alignItems: "center", padding: "12px 13px", background: "var(--terminal-fill)", borderRadius: 12 }}>
            <span style={{ flex: "none", color: "var(--terminal-ink)", display: "flex" }}><Icon name="terminal" size={16} color="var(--terminal-ink)" /></span>
            <code style={{ flex: 1, minWidth: 0, fontFamily: "var(--f-mono, ui-monospace, monospace)", fontSize: 11.5, color: "var(--terminal-ink)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{AGENT_SETUP[setupAgent.id]}</code>
            <button className="press" onClick={doCopy} style={{ flex: "none", display: "inline-flex", alignItems: "center", gap: 5, background: "var(--accent)", color: "var(--accent-ink)", border: "none", borderRadius: 8, padding: "7px 11px", fontFamily: "var(--f-display)", fontSize: 12, fontWeight: 700, cursor: "pointer" }}>
              {copied ? <><Icon name="check" size={13} stroke={2.2} color="var(--accent-ink)" /> Copied</> : "Copy"}
            </button>
          </div>
        </div>
      )}

      <div style={{ display: "flex", gap: 9, alignItems: "flex-start", padding: "13px 14px", background: "color-mix(in srgb, var(--accent) 14%, var(--bg-card))", border: "1px solid var(--accent)", borderRadius: 12, marginTop: 18 }}>
        <span style={{ flex: "none", marginTop: 1, color: "var(--accent)" }}><Icon name="shield" size={16} color="var(--accent)" /></span>
        <span style={{ flex: 1, fontFamily: "var(--f-display)", fontSize: 13.5, fontWeight: 600, color: "var(--ink)", lineHeight: 1.45 }}>
          Propose-only access. An agent never holds or moves your money on its own. Revoke any connection anytime.
        </span>
      </div>
    </Body>
    <Dock>
      {count > 0 ? (
        <Btn full onClick={onNext}>Continue <Icon name="arrow" size={15} color="var(--accent-ink)" /></Btn>
      ) : (
        <SkipLink onClick={onSkip}>Skip for now</SkipLink>
      )}
    </Dock>

    {/* OAuth redirect — leave to the agent's app to authorize, then return */}
    {redirectAgent && (
      <>
        <div style={{ position: "absolute", inset: 0, zIndex: 60, background: "color-mix(in srgb, var(--bg) 70%, transparent)", backdropFilter: "blur(8px)", WebkitBackdropFilter: "blur(8px)" }} />
        <div style={{ position: "absolute", inset: 0, zIndex: 61, display: "flex", alignItems: "center", justifyContent: "center", padding: 28 }}>
          <div className="yo-enter" style={{ width: "100%", maxWidth: 280, background: "var(--bg-card)", border: "1px solid var(--rule-2)", borderRadius: 16, padding: "26px 22px", textAlign: "center", boxShadow: "0 16px 40px -16px rgba(0,0,0,0.34)" }}>
            <div style={{ display: "flex", alignItems: "center", justifyContent: "center", gap: 12, marginBottom: 17 }}>
              <span style={{ width: 38, height: 38, flex: "none", border: "1px solid var(--rule-2)", display: "grid", placeItems: "center", fontFamily: "var(--f-display)", fontSize: 17, fontWeight: 700, color: "var(--ink)" }}>Y</span>
              <LiveDot size={7} color="var(--accent)" />
              <span style={{ width: 38, height: 38, flex: "none", border: "1px solid var(--accent)", display: "grid", placeItems: "center", fontFamily: "var(--f-display)", fontSize: 17, fontWeight: 700, color: "var(--accent)" }}>{redirectAgent.name[0]}</span>
            </div>
            <div style={{ fontFamily: "var(--f-display)", fontSize: 16, fontWeight: 700, letterSpacing: "-0.02em" }}>Opening {redirectAgent.name}…</div>
            <div style={{ fontFamily: "var(--f-display)", fontSize: 13, color: "var(--ink-3)", marginTop: 6, lineHeight: 1.45 }}>Authorize Yoshi in {redirectAgent.name}, then you'll come right back here.</div>
          </div>
        </div>
      </>
    )}
  </Screen>
  );
};

/* =============================================================
   11 · DISCLOSURES — the last gate before Yoshi gets to work.
   Institutional register: concede the fine print, lay it out plainly.
   Tapping continue is the acknowledgment; the seam draws as you sign.
   ============================================================= */
const AckRow = ({ label, href, children, last }) => (
  <div style={{ padding: "15px 0", borderBottom: last ? "none" : "1px dashed var(--rule)" }}>
    <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
      <Eyebrow color="var(--accent)" style={{ fontSize: 9.5 }}>{label}</Eyebrow>
      {href && (
        <a href={href} target="_blank" rel="noopener noreferrer" className="press" aria-label={label + " document"} style={{ marginLeft: "auto", flex: "none", display: "inline-flex", color: "var(--ink-3)" }}>
          <Icon name="external" size={14} color="var(--ink-3)" />
        </a>
      )}
    </div>
    <span style={{ display: "block", fontFamily: "var(--f-display)", fontSize: 13.5, color: "var(--ink)", lineHeight: 1.48, marginTop: 5, textWrap: "pretty" }}>{children}</span>
  </div>
);

const PartnerRow = ({ name, role, member, href, onClick, first }) => {
  const common = {
    textDecoration: "none", width: "100%", display: "grid", gridTemplateColumns: "1fr auto", gap: 12, alignItems: "center",
    padding: "13px 0", background: "none", border: "none", borderTop: `1px ${first ? "solid" : "dashed"} var(--rule)`,
    color: "var(--ink)", cursor: "pointer", textAlign: "left" };
  const body = (
    <>
      <span style={{ minWidth: 0 }}>
        <span style={{ display: "block", fontFamily: "var(--f-display)", fontSize: 14.5, fontWeight: 700, letterSpacing: "-0.015em" }}>{name}</span>
        <span style={{ display: "block", fontFamily: "var(--f-mono)", fontSize: 9, letterSpacing: "0.05em", textTransform: "uppercase", color: "var(--ink-3)", marginTop: 3, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{role} · {member}</span>
      </span>
      <span style={{ display: "inline-flex", alignItems: "center", gap: 5, flex: "none", fontFamily: "var(--f-display)", fontSize: 11.5, fontWeight: 600, color: "var(--ink-2)" }}>
        Agreements <Icon name="external" size={14} color="var(--ink-3)" />
      </span>
    </>
  );
  return onClick
    ? <button type="button" className="press" onClick={onClick} style={common}>{body}</button>
    : <a href={href} target="_blank" rel="noopener noreferrer" className="press" style={common}>{body}</a>;
};

/* The Apex agreements + disclosures, as an in-app push screen reached from the
   brokerage row. Each document opens its PDF; the disclosures live at the foot. */
const APEX_DOCS = [
  ["Customer Account Agreement", "https://storage.googleapis.com/apexclearing-account-agreements-prd-00/SCAA-OBD-20260318-EN.pdf"],
  ["Customer Information Brochure", "https://library.apexfintechsolutions.com/wp-content/uploads/2024/12/Apex-Direct-Customer-Infromation-Brochure.pdf"],
  ["Privacy Policy", "https://library.apexfintechsolutions.com/wp-content/uploads/2025/04/AFBS-Privacy-Policy.pdf"],
  ["Terms of Service", "https://library.apexfintechsolutions.com/wp-content/uploads/2025/04/AFBS-Terms-of-Service-Template.pdf"],
  ["CIP Notice", "https://library.apexfintechsolutions.com/wp-content/uploads/2025/04/FINRA-CIP-Notice.pdf"],
  ["Business Continuity Plan", "https://library.apexfintechsolutions.com/wp-content/uploads/2024/12/Business-Continuity-Plan-Policy-11-08-2024.pdf"],
  ["Fee Sheet", "https://library.apexfintechsolutions.com/wp-content/uploads/2024/12/Apex-Direct-Misc-Services-Fee-Sheet-11.2024.pdf"],
];

const ApexAgreements = ({ onClose }) => {
  const link = { color: "var(--ink-2)", textDecoration: "underline", textUnderlineOffset: 2 };
  const disc = { fontFamily: "var(--f-display)", fontSize: 11.5, color: "var(--ink-3)", lineHeight: 1.58, marginTop: 12, marginBottom: 0, textWrap: "pretty", letterSpacing: "0.003em" };
  return (
    <div style={{ position: "absolute", inset: 0, zIndex: 80, background: "var(--bg)", display: "flex", flexDirection: "column", animation: "sheet-in 320ms cubic-bezier(0.16,1,0.30,1) both" }} data-screen-label="Apex agreements">
      <NavBar title="Apex Clearing Corporation" sub="Brokerage agreements" right={
        <button className="press" onClick={onClose} aria-label="Close" style={{ background: "none", border: "none", padding: 6, margin: "0 -6px", display: "flex", color: "var(--ink)", cursor: "pointer", flex: "none" }}>
          <Icon name="close" size={20} />
        </button>
      } />
      <div className="scroll" style={{ flex: 1, minHeight: 0, padding: "12px 24px 28px" }}>
        <Eyebrow color="var(--ink-2)">Documents</Eyebrow>
        <div style={{ display: "grid", marginTop: 4 }}>
          {APEX_DOCS.map(([name, url], i) => (
            <a key={name} href={url} target="_blank" rel="noopener noreferrer" className="press" style={{
              textDecoration: "none", display: "grid", gridTemplateColumns: "1fr auto", gap: 12, alignItems: "center",
              padding: "14px 0", borderTop: `1px ${i === 0 ? "solid" : "dashed"} var(--rule)`, color: "var(--ink)" }}>
              <span style={{ fontFamily: "var(--f-display)", fontSize: 14, fontWeight: 600, letterSpacing: "-0.01em" }}>{name}</span>
              <Icon name="external" size={15} color="var(--ink-3)" />
            </a>
          ))}
        </div>

        <div style={{ marginTop: 26, paddingTop: 18, borderTop: "1px solid var(--rule-2)" }}>
          <p style={{ ...disc, marginTop: 0 }}>
            Brokerage services are provided by Apex Clearing Corporation, an SEC-registered broker-dealer and member FINRA/SIPC. Learn more about Apex at{" "}
            <a href="https://brokercheck.finra.org/" target="_blank" rel="noopener noreferrer" style={link}>FINRA BrokerCheck</a>.
          </p>
          <p style={disc}>
            Investing in securities involves risks, including the potential loss of principal. Securities investments are not FDIC insured, are not bank guaranteed, and may lose value. Before investing, please carefully review your investment objectives, risk tolerance, charges, and expenses. Yoshi is not owned or operated by Apex Clearing Corporation.
          </p>
          <p style={{ ...disc, display: "flex", alignItems: "center", gap: 7 }}>
            <span>For additional information about SIPC coverage, visit{" "}
              <a href="https://www.sipc.org" target="_blank" rel="noopener noreferrer" style={link}>sipc.org</a>.</span>
          </p>
        </div>
      </div>
    </div>
  );
};

const Disclosures = ({ onNext }) => {
  const [signing, setSigning] = useState(false);
  const [showApex, setShowApex] = useState(false);
  const sign = () => { if (signing) return; setSigning(true); setTimeout(() => onNext(), 760); };
  const link = { color: "var(--ink-2)", textDecoration: "underline", textUnderlineOffset: 2 };

  return (
    <Screen style={{ position: "relative" }}>
      <Body>
        <H>A bit of<Brk />fine <Accent>print.</Accent></H>
        <Sub style={{ maxWidth: "none", whiteSpace: "nowrap" }}>By tapping "Confirm &amp; continue" below,</Sub>

        {/* primary acknowledgment card — flagged with the 2px seam top-bar */}
        <div style={{ position: "relative", marginTop: 20, background: "var(--bg-card)", border: "1px solid var(--rule-2)", borderRadius: 14, padding: "4px 16px 6px", overflow: "hidden" }}>
          <span style={{ position: "absolute", top: 0, left: 0, right: 0, height: 2, background: "var(--accent)" }} />
          <AckRow label="E-sign consent" href="https://yoshi.ai/esign-consent/">
            You consent to electronic delivery and signature of your account documents.
          </AckRow>
          <AckRow label="Customer agreements" last>
            You've read, acknowledged, and agree to the agreements that govern your Yoshi account.
          </AckRow>
        </div>

        {/* the institutions behind the account — each opens its agreements */}
        <div style={{ marginTop: 22, marginBottom: 4 }}><Eyebrow color="var(--ink-2)">Provided by</Eyebrow></div>
        <div style={{ display: "grid" }}>
          <PartnerRow first name="Column N.A." role="Banking" member="Member FDIC" href="https://column.com/legal" />
          <PartnerRow name="Apex Clearing Corporation" role="Brokerage" member="Member FINRA/SIPC" onClick={() => setShowApex(true)} />
        </div>

        {/* the required fine print, in full */}
        <p style={{ fontFamily: "var(--f-display)", fontSize: 10.5, color: "var(--ink-3)", lineHeight: 1.55, marginTop: 22, marginBottom: 4, textWrap: "pretty", letterSpacing: "0.004em" }}>
          Brokerage services are provided by Apex Clearing Corporation, an SEC-registered broker-dealer and member FINRA/SIPC. Learn more about Apex at{" "}
          <a href="https://brokercheck.finra.org/" target="_blank" rel="noopener noreferrer" style={link}>FINRA BrokerCheck</a>. Yoshi is a fintech company, not an FDIC-insured depository institution. Banking services provided through Column N.A., Members FDIC. Deposit insurance covers the failure of an insured bank.
        </p>
      </Body>
      <Dock>
        {/* the seam draws across at the moment of signing — the brand's approval signature */}
        <div style={{ height: 1, background: "var(--accent)", opacity: 0.6, transformOrigin: "left center", transform: `scaleX(${signing ? 1 : 0})`, transition: "transform 700ms linear" }} />
        <Btn full onClick={sign} disabled={signing}>
          {signing
            ? <><LiveDot size={6} color="var(--accent-ink)" /> Signing…</>
            : <>Confirm &amp; continue <Icon name="arrow" size={15} color="var(--accent-ink)" /></>}
        </Btn>
      </Dock>

      {showApex && <ApexAgreements onClose={() => setShowApex(false)} />}
    </Screen>
  );
};

/* =============================================================
   12 · OFF TO WORK — the landing. A calm "you're in" beat, the
   mark working like the provisioning screen, then what's waiting.
   ============================================================= */
const OffToWork = ({ agents = [], accent = "#6c9a5c", showJob = true, onEnter }) => {
  const [ready, setReady] = useState(false);
  const [shown, setShown] = useState(false);
  useEffect(() => { const r = setTimeout(() => setReady(true), 1300); return () => clearTimeout(r); }, []);
  useEffect(() => { if (!ready) return; const t = setTimeout(() => setShown(true), 40); return () => clearTimeout(t); }, [ready]);
  const ink = "#f3f1ea", m55 = "rgba(243,241,234,0.55)", m18 = "rgba(243,241,234,0.18)";
  const mark = `url(${(typeof window !== "undefined" && window.__resources && window.__resources.logoBlack) || "assets/logo-mark-black.png"})`;
  const offWeb = usePlatform() === "web";
  const enterBtn = (
    <button className="press" onClick={() => onEnter(null)} style={{ width: offWeb ? "auto" : "100%", minWidth: offWeb ? 200 : undefined, padding: "16px 22px", borderRadius: 12, border: "none", cursor: "pointer", background: accent, color: "#141310", fontFamily: "var(--f-display)", fontSize: 15, fontWeight: 700, letterSpacing: "-0.01em", display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 8 }}>
      Enter Yoshi <Icon name="arrow" size={15} color="#141310" />
    </button>
  );

  return (
    <Screen style={{ background: "#141310", color: ink }}>
      <div className="scroll" style={{ flex: 1, minHeight: 0, padding: "12px 24px 8px", display: "flex", flexDirection: "column" }}>
        {/* the mark, working — same calm beat as provisioning */}
        <div style={{ display: "flex", flexDirection: "column", alignItems: "center", textAlign: "center", paddingTop: 76 }}>
          <div className="yo-grow" style={{ width: 60, height: 68, background: accent,
            WebkitMaskImage: mark, maskImage: mark, WebkitMaskSize: "contain", maskSize: "contain",
            WebkitMaskRepeat: "no-repeat", maskRepeat: "no-repeat", WebkitMaskPosition: "center", maskPosition: "center" }} />
          <div className="yo-enter" data-delay="1" style={{ display: "flex", alignItems: "center", gap: 9, marginTop: 24 }}>
            <LiveDot size={8} color={accent} />
            <span style={{ fontFamily: "var(--f-display)", fontSize: 10.5, fontWeight: 700, letterSpacing: "0.16em", textTransform: "uppercase", color: accent }}>Your account is live</span>
          </div>
          <div className="yo-enter" data-delay="2" style={{ fontFamily: "var(--f-display)", fontSize: 40, fontWeight: 700, letterSpacing: "-0.035em", lineHeight: 1.0, marginTop: 14, color: ink }}>
            Yoshi is off<br />to <span style={{ color: accent }}>work.</span>
          </div>
        </div>

        {/* what's genuinely waiting inside — fades in slowly, row by row */}
        {ready && (
          <div style={{ marginTop: 34, width: "100%", maxWidth: 320, marginLeft: "auto", marginRight: "auto" }}>
            <div style={{ fontFamily: "var(--f-display)", fontSize: 10.5, fontWeight: 700, letterSpacing: "0.14em", textTransform: "uppercase", color: m55, marginBottom: 12, textAlign: "center",
              opacity: shown ? 1 : 0, transform: shown ? "translateY(0)" : "translateY(6px)", transition: "opacity 900ms ease, transform 900ms ease" }}>Inside your account</div>
            {[
              ["bulb", "Yoshi's read of your finances"],
              ["route", "A short list to get Yoshi working for you"],
              ["eye", "Eyes on your money, day and night"],
            ].map(([ic, tx], i) => (
              <div key={tx} style={{ display: "flex", alignItems: "center", justifyContent: "center", gap: 12, padding: "10px 0", borderBottom: `1px dashed ${m18}`,
                opacity: shown ? 1 : 0, transform: shown ? "translateY(0)" : "translateY(8px)",
                transition: `opacity 1000ms ease ${360 + i * 340}ms, transform 1000ms ease ${360 + i * 340}ms` }}>
                <span style={{ color: accent, flex: "none" }}><Icon name={ic} size={18} color={accent} /></span>
                <span style={{ fontFamily: "var(--f-display)", fontSize: 13.5, fontWeight: 500, color: ink }}>{tx}</span>
              </div>
            ))}
          </div>
        )}
        {offWeb && ready && (
          <div className="yo-enter" style={{ display: "flex", justifyContent: "center", marginTop: 30 }}>{enterBtn}</div>
        )}
      </div>
      {!offWeb && (
      <div style={{ flex: "none", padding: "12px 24px 26px" }}>
        {enterBtn}
      </div>
      )}
    </Screen>
  );
};

Object.assign(window, { PlaidLink, BANKS, Funding, FundDeposit, Agent, AGENTS, Disclosures, OffToWork });
