/* profile.jsx — the "You" hamburger hub. A clean menu: identity, open-a-new
   account (accordion), and entries into Settings / Documents / Help. Settings
   is its own screen with collapsible sections. */

const Toggle = ({ on, onChange }) =>
<button className="press" role="switch" aria-checked={on} onClick={() => onChange(!on)} style={{ width: 40, height: 23, padding: 0, position: "relative", background: on ? "var(--accent)" : "var(--rule-2)", border: "none", borderRadius: 999, cursor: "pointer", flex: "none", transition: "background 180ms ease" }}>
    <span style={{ position: "absolute", top: 2.5, left: on ? 20 : 2.5, width: 18, height: 18, borderRadius: "50%", background: "#fff", transition: "left 180ms var(--ease)", boxShadow: "0 1px 3px rgba(0,0,0,0.3)" }} />
  </button>;


const SettingRow = ({ label, sub, right, last, onClick }) => {
  return (
    <div className={onClick ? "press" : undefined} role={onClick ? "button" : undefined} tabIndex={onClick ? 0 : undefined}
    onClick={onClick} onKeyDown={onClick ? (e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); onClick(e); } } : undefined}
    style={{ width: "100%", textAlign: "left", background: "none", border: "none", color: "var(--ink)", display: "flex", alignItems: "center", gap: 12, padding: "13px 16px", borderBottom: last ? "none" : "1px solid var(--rule)", cursor: onClick ? "pointer" : "default" }}>
    <div style={{ flex: 1, minWidth: 0 }}>
      <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(14), fontWeight: 500 }}>{label}</div>
      {sub && <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11.5), color: "var(--ink-3)", marginTop: 3 }}>{sub}</div>}
    </div>
    {right}
  </div>
  );
};


/* hold-to-confirm — press and hold 3s to commit a sensitive change */
const HoldButton = ({ label, onConfirm }) => {
  const [progress, setProgress] = useState(0);
  const raf = useRef(null);
  const startT = useRef(0);
  const DURATION = 3000;
  const stop = (done) => {
    if (raf.current) cancelAnimationFrame(raf.current);
    raf.current = null;startT.current = 0;
    setProgress(0);
    if (done) onConfirm();
  };
  const frame = (t) => {
    if (!startT.current) startT.current = t;
    const p = Math.min(1, (t - startT.current) / DURATION);
    setProgress(p);
    if (p >= 1) {stop(true);return;}
    raf.current = requestAnimationFrame(frame);
  };
  const begin = (e) => {e.preventDefault();startT.current = 0;raf.current = requestAnimationFrame(frame);};
  const holding = progress > 0 && progress < 1;
  return (
    <button className="press"
    onPointerDown={begin} onPointerUp={() => stop(false)} onPointerLeave={() => stop(false)} onPointerCancel={() => stop(false)}
    style={{ position: "relative", overflow: "hidden", width: "100%", padding: "12px 16px", border: "1px solid var(--hold-accent)", background: "transparent", color: "var(--hold-accent)", fontFamily: "var(--f-display)", fontSize: typeSize(13), fontWeight: 600, cursor: "pointer", borderRadius: 10, touchAction: "none", WebkitUserSelect: "none", userSelect: "none" }}>
      <span style={{ position: "absolute", top: 0, left: 0, bottom: 0, width: `${progress * 100}%`, background: "var(--hold-accent)", opacity: 0.32, transition: holding ? "none" : "width 180ms ease" }} />
      <span style={{ position: "relative" }}>{holding ? "Keep holding…" : label}</span>
    </button>);

};

const TILE = { width: 34, height: 34, flex: "none", border: "1px solid var(--rule-2)", borderRadius: 999, display: "grid", placeItems: "center" };

/* square check control used by the close-accounts list */
const CheckBox = ({ on, disabled }) =>
<span style={{ flex: "none", width: 20, height: 20, borderRadius: 5, display: "grid", placeItems: "center", border: "1.5px solid " + (on ? "var(--accent)" : "var(--rule-2)"), background: on ? "var(--accent)" : "transparent", opacity: disabled ? 0.4 : 1, transition: "background 140ms ease, border-color 140ms ease" }}>
    {on && <Icon name="check" size={13} color="var(--accent-ink)" stroke={2.4} />}
  </span>;


/* close-accounts — multi-select with eligibility gating. An account can be
   closed only when (1) it has no pending trades, transfers, or unsettled funds
   and (2) its balance is $0.00. Ineligible accounts are dimmed and locked with the
   blocking reason; eligible ones are tappable and selectable (incl. select-all). */
const CLOSEABLE = [
{ id: "ca-bro", name: "Brokerage", sub: "Yoshi · Individual Taxable", bal: 48210.33, pending: 0, holds: true },
{ id: "ca-roth", name: "Roth IRA", sub: "Yoshi · Retirement", bal: 22640.10, pending: 0, holds: true },
{ id: "ca-crypto", name: "Crypto", sub: "Yoshi · Spot ••8841", bal: 5121.74, pending: 1, holds: true },
{ id: "ca-cash", name: "Cash", sub: "Yoshi ••8841", bal: 1284.50, pending: 0, holds: false },
{ id: "ca-legacy", name: "Brokerage (2023)", sub: "Yoshi · Individual Taxable", bal: 0, pending: 0, holds: true },
{ id: "ca-paper", name: "Test drive 1", sub: "Yoshi · Simulated", bal: 0, pending: 0, holds: true }];

const closeBlocker = (a) =>
a.pending ? `${a.pending} pending item${a.pending > 1 ? "s" : ""} — must settle before closing` :
a.bal > 0 ? a.holds ? "Sell or transfer holdings to reach $0.00" : "Withdraw balance to $0.00 first" :
null;

/* ---- hidden-accounts (shared store with the Accounts tab) ----------------
   The Accounts tab hides an account via ••• → eye; it persists to this same
   localStorage key and broadcasts "yoshi-hidden". Surfaced here read+unhide. */
const P_HIDDEN_KEY = "yoshi_hidden_accts";
const HIDEABLE_META = {
  Chase: "Checking ••4417 · external",
  Schwab: "Brokerage ••5520 · external",
  Coinbase: "Crypto ••3097 · external"
};
const useHiddenP = () => {
  const read = () => {try {return JSON.parse(localStorage.getItem(P_HIDDEN_KEY) || "[]");} catch (e) {return [];}};
  const [hidden, setHidden] = useState(read);
  useEffect(() => {const f = () => setHidden(read());window.addEventListener("yoshi-hidden", f);return () => window.removeEventListener("yoshi-hidden", f);}, []);
  const unhide = (name) => {try {const cur = read();localStorage.setItem(P_HIDDEN_KEY, JSON.stringify(cur.filter((n) => n !== name)));} catch (e) {}window.dispatchEvent(new CustomEvent("yoshi-hidden"));};
  return [hidden, unhide];
};

const HiddenAccounts = () => {
  const [hidden, unhide] = useHiddenP();
  const list = hidden.filter((n) => HIDEABLE_META[n]);
  return (
    <div style={{ padding: "2px 16px 16px" }}>
      <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11.5), color: "var(--ink-3)", lineHeight: 1.55, marginBottom: list.length ? 13 : 0 }}>
        Accounts you've hidden from your totals and summaries. <span style={{ color: "var(--ink-2)", fontWeight: 600 }}></span>.
      </div>
      {list.length === 0 ?
      <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(12.5), color: "var(--ink-3)", padding: "6px 0" }}>No hidden accounts.</div> :
      <div style={{ border: "1px solid var(--rule-2)", borderRadius: 12, overflow: "hidden" }}>
        {list.map((name, i) =>
        <div key={name} style={{ display: "flex", alignItems: "center", gap: 12, padding: "12px 13px", borderBottom: i === list.length - 1 ? "none" : "1px solid var(--rule)" }}>
          <Icon name="eye" size={17} color="var(--ink-3)" stroke={1.6} />
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(14), fontWeight: 600 }}>{name}</div>
            <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11), color: "var(--ink-3)", marginTop: 3 }}>{HIDEABLE_META[name]}</div>
          </div>
          <Btn kind="ghost" onClick={() => unhide(name)} style={{ padding: "7px 12px", fontSize: typeSize(12), whiteSpace: "nowrap" }}>Unhide</Btn>
        </div>
        )}
      </div>}
    </div>);

};

const CloseAccounts = () => {
  const [sel, setSel] = useState([]);
  const [closed, setClosed] = useState([]);
  const [deleted, setDeleted] = useState(false);
  const list = CLOSEABLE.filter((a) => !closed.includes(a.id));
  const eligible = list.filter((a) => !closeBlocker(a));
  const toggle = (id) => setSel((s) => s.includes(id) ? s.filter((x) => x !== id) : [...s, id]);
  const allSel = eligible.length > 0 && eligible.every((a) => sel.includes(a.id));
  const toggleAll = () => setSel(allSel ? [] : eligible.map((a) => a.id));
  const commit = () => {const n = sel.length;setClosed((c) => [...c, ...sel]);setSel([]);return n;};

  return (
    <div style={{ padding: "2px 16px 16px" }}>
      <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11.5), color: "var(--ink-3)", lineHeight: 1.55, marginBottom: 13 }}>
        Closing is permanent. An account can be closed only once it has <span style={{ color: "var(--ink-2)", fontWeight: 600 }}>no pending trades, transfers, or unsettled funds</span> and a <span style={{ color: "var(--ink-2)", fontWeight: 600 }}>$0.00 balance</span>.
      </div>

      {closed.length > 0 &&
      <div style={{ display: "flex", alignItems: "center", gap: 8, padding: "10px 12px", marginBottom: 12, border: "1px solid color-mix(in srgb, var(--accent) 35%, var(--rule-2))", background: "color-mix(in srgb, var(--accent) 8%, transparent)", borderRadius: 10 }}>
          <Icon name="check" size={15} color="var(--accent)" stroke={2.2} />
          <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(12.5), fontWeight: 600, color: "var(--ink)" }}>{closed.length} account{closed.length > 1 ? "s" : ""} closed</span>
        </div>}

      {list.length === 0 ?
      <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(12.5), color: "var(--ink-3)", padding: "8px 0" }}>No accounts available to close.</div> :
      <>
          {eligible.length > 1 &&
        <button className="press" onClick={toggleAll} style={{ display: "flex", alignItems: "center", gap: 10, background: "none", border: "none", padding: "0 0 11px", cursor: "pointer" }}>
              <CheckBox on={allSel} />
              <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(12.5), fontWeight: 600, color: "var(--ink-2)" }}>Select all eligible ({eligible.length})</span>
            </button>}

          <div style={{ border: "1px solid var(--rule-2)", borderRadius: 12, overflow: "hidden" }}>
            {list.map((a, i) => {
            const block = closeBlocker(a);
            const on = sel.includes(a.id);
            const last = i === list.length - 1;
            return (
              <button key={a.id} className="press" disabled={!!block} onClick={() => !block && toggle(a.id)}
              style={{ width: "100%", textAlign: "left", display: "flex", alignItems: "center", gap: 12, padding: "12px 13px", background: on ? "color-mix(in srgb, var(--accent) 9%, transparent)" : "transparent", border: "none", borderBottom: last ? "none" : "1px solid var(--rule)", cursor: block ? "default" : "pointer", opacity: block ? 0.6 : 1 }}>
                  <CheckBox on={on} disabled={!!block} />
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(14), fontWeight: 600, color: "var(--ink)" }}>{a.name}</div>
                    <div style={{ display: "flex", alignItems: "center", gap: 5, marginTop: 3 }}>
                      {a.pending > 0 && <Icon name="clock" size={11} color="var(--signal-neg)" stroke={1.8} />}
                      <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11), lineHeight: 1.4, color: block ? "var(--signal-neg)" : "var(--accent)", fontWeight: block ? 500 : 600 }}>{block || "Ready to close"}</span>
                    </div>
                  </div>
                  <Money value={a.bal} size={12.5} color={a.bal > 0 ? "var(--ink-2)" : "var(--ink-3)"} />
                </button>);

          })}
          </div>

          <div style={{ marginTop: 14 }}>
            {sel.length > 0 ?
          <HoldButton label={`Hold to close ${sel.length} account${sel.length > 1 ? "s" : ""}`} onConfirm={commit} /> :
          <div style={{ width: "100%", padding: "12px 16px", border: "1px solid var(--rule-2)", borderRadius: 10, textAlign: "center", fontFamily: "var(--f-display)", fontSize: typeSize(13), fontWeight: 600, color: "var(--ink-3)" }}>
                Select accounts to close
              </div>}
          </div>
        </>}

      {/* danger zone — delete the entire Yoshi account */}
      <div style={{ marginTop: 22, paddingTop: 18, borderTop: "1px solid var(--rule)" }}>
        <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(13), fontWeight: 700, color: "var(--signal-danger)", letterSpacing: "-0.01em" }}>Delete your Yoshi account</div>
        <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11.5), color: "var(--ink-3)", lineHeight: 1.55, marginTop: 5 }}>
          Permanently closes every Yoshi account and removes your profile. All balances must be withdrawn first. Statements and tax documents stay downloadable for seven years.
        </div>
        {deleted ?
        <div style={{ display: "flex", alignItems: "center", gap: 8, padding: "11px 12px", marginTop: 12, border: "1px solid color-mix(in srgb, var(--signal-danger) 40%, var(--rule-2))", background: "color-mix(in srgb, var(--signal-danger) 8%, transparent)", borderRadius: 10 }}>
          <Icon name="check" size={15} color="var(--signal-danger)" stroke={2.2} />
          <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(12.5), fontWeight: 600, color: "var(--ink)" }}>Deletion requested — we'll email you to confirm.</span>
        </div> :
        <div style={{ marginTop: 12, "--hold-accent": "var(--signal-danger)" }}>
          <HoldButton label="Hold to delete your Yoshi account" onConfirm={() => setDeleted(true)} />
        </div>}
      </div>
    </div>);

};


/* a tappable hub row with a leading icon tile */
const MenuRow = ({ icon, label, sub, onClick, last }) =>
<button className="press" onClick={onClick} style={{ width: "100%", background: "none", border: "none", borderBottom: last ? "none" : "1px solid var(--rule)", textAlign: "left", cursor: "pointer", display: "flex", alignItems: "center", gap: 12, padding: "14px 16px" }}>
    <Icon name={icon} size={22} stroke={1.5} color="var(--ink)" />
    <div style={{ flex: 1, minWidth: 0 }}>
      <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(14.5), fontWeight: 600 }}>{label}</div>
      {sub && <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11.5), color: "var(--ink-3)", marginTop: 3 }}>{sub}</div>}
    </div>
    <Icon name="back" size={15} color="var(--ink-3)" style={{ transform: "scaleX(-1)" }} />
  </button>;


/* a collapsible group — tap the header to expand */
const Accordion = ({ icon, label, sub, children, defaultOpen, last, tag }) => {
  const [open, setOpen] = useState(!!defaultOpen);
  return (
    <div style={{ borderBottom: last ? "none" : "1px solid var(--rule)" }}>
      <button className="press" onClick={() => setOpen((o) => !o)} style={{ width: "100%", background: "none", border: "none", textAlign: "left", cursor: "pointer", display: "flex", alignItems: "center", gap: 12, padding: "14px 16px" }}>
        {icon && <Icon name={icon} size={22} stroke={1.5} color="var(--ink)" />}
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 7 }}>
            <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(14.5), fontWeight: 600 }}>{label}</span>
            {tag && <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(8.5), fontWeight: 700, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--ink-3)", border: "1px solid var(--rule-2)", padding: "2px 6px" }}>{tag}</span>}
          </div>
          {sub && <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11.5), color: "var(--ink-3)", marginTop: 3 }}>{sub}</div>}
        </div>
        <Icon name="down" size={16} color="var(--ink-3)" style={{ transform: open ? "rotate(180deg)" : "none", transition: "transform 180ms ease" }} />
      </button>
      {open && <div>{children}</div>}
    </div>);

};

const COMING_SOON_ACCOUNTS = [
["Crypto", "A dedicated spot wallet"],
["Retirement", "Roth & Traditional IRA"],
["Joint", "Shared with another person"]];


/* ---- profile form fields · Yoshi-styled (sharp, hairline) ----------------- */
const PInput = ({ label, value, onChange, placeholder, mono }) =>
<div style={{ marginBottom: 12 }}>
    {label && <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11), fontWeight: 600, color: "var(--ink-2)", marginBottom: 6 }}>{label}</div>}
    <input value={value || ""} onChange={(e) => onChange && onChange(e.target.value)} placeholder={placeholder}
  style={{ width: "100%", padding: "11px 12px", background: "var(--bg-2)", border: "1px solid var(--rule-2)", outline: "none", color: "var(--ink)", fontFamily: mono ? "var(--f-mono)" : "var(--f-display)", fontSize: typeSize(14) }} />
  </div>;

const PSelect = ({ label, value, onChange, options }) =>
<div style={{ marginBottom: 12 }}>
    {label && <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11), fontWeight: 600, color: "var(--ink-2)", marginBottom: 6 }}>{label}</div>}
    <div style={{ position: "relative" }}>
      <select value={value} onChange={(e) => onChange && onChange(e.target.value)}
    style={{ width: "100%", padding: "11px 30px 11px 12px", background: "var(--bg-2)", border: "1px solid var(--rule-2)", outline: "none", color: value && value !== "Select" ? "var(--ink)" : "var(--ink-3)", fontFamily: "var(--f-display)", fontSize: typeSize(14), appearance: "none", WebkitAppearance: "none", borderRadius: 0, cursor: "pointer" }}>
        {options.map((o) => <option key={o} value={o}>{o}</option>)}
      </select>
      <Icon name="down" size={15} color="var(--ink-3)" style={{ position: "absolute", right: 10, top: "50%", marginTop: -7, pointerEvents: "none" }} />
    </div>
  </div>;

const PTwo = ({ children }) => <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>{children}</div>;
const PDivider = () => <div style={{ height: 1, background: "var(--rule)", margin: "6px 0 14px" }} />;

const PersonalInfoForm = () => {
  const [f, setF] = useState({ preferred: "Rivka", first: "Rivka", last: "Lipson", tcFirst: "", tcLast: "", tcEmail: "" });
  const set = (k) => (v) => setF((s) => ({ ...s, [k]: v }));
  return (
    <div style={{ padding: "4px 16px 16px" }}>
      <PInput label="Preferred name" value={f.preferred} onChange={set("preferred")} />
      <PTwo>
        <PInput label="First name" value={f.first} onChange={set("first")} />
        <PInput label="Last name" value={f.last} onChange={set("last")} />
      </PTwo>
      <PDivider />
      <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(13), fontWeight: 600, marginBottom: 10 }}>Trusted contact</div>
      <PTwo>
        <PInput label="First name" value={f.tcFirst} onChange={set("tcFirst")} placeholder="First name" />
        <PInput label="Last name" value={f.tcLast} onChange={set("tcLast")} placeholder="Last name" />
      </PTwo>
      <PInput label="Email" value={f.tcEmail} onChange={set("tcEmail")} placeholder="name@email.com" />
      <PDivider />
      <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
        <div style={{ flex: 1 }}>
          <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(13.5), fontWeight: 600 }}>Address</div>
          <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11), color: "var(--ink-3)", marginTop: 3 }}>148 Mercer St, New York, NY</div>
        </div>
        <Btn kind="ghost" onClick={() => {}} style={{ padding: "8px 13px", fontSize: typeSize(12) }}>Edit address</Btn>
      </div>
    </div>);

};

const INVESTOR_PROFILE = {
  version: 3,
  source: "User attested",
  status: "Complete",
  attested: "Jun 24, 2026",
  risk: "Moderate",
  horizon: "10 years",
  objectives: ["Growth", "Balanced"],
  liquidity: "Moderate",
  income: "$100k–$249k",
  liquid: "$250k–$999k",
  netWorth: "$1M–$4.99M",
  tax: "High",
  experience: "Good",
  employment: "Employed",
  dependents: "2",
  expenses: [{ description: "Home down payment", timeframe: "3 years", amount: "$100,000.00" }],
  constraints: ["Avoid single-stock concentration"],
  considerations: "Prefers ESG-aligned holdings.",
  facts: [
    "Would stay invested or rebalance rather than sell during a 20.00% market decline.",
    "No material external concentrated stock, crypto, options, margin, or private investment exposure disclosed."
  ]
};

const ReadOnlyPill = ({ children, tone }) =>
<span style={{ display: "inline-flex", alignItems: "center", height: 22, padding: "0 8px", border: "1px solid " + (tone === "accent" ? "color-mix(in srgb, var(--accent) 45%, var(--rule-2))" : "var(--rule-2)"), background: tone === "accent" ? "color-mix(in srgb, var(--accent) 10%, transparent)" : "transparent", color: tone === "accent" ? "var(--accent)" : "var(--ink-3)", fontFamily: "var(--f-mono)", fontSize: typeSize(10), fontWeight: 700, letterSpacing: "0.04em", textTransform: "uppercase", whiteSpace: "nowrap" }}>{children}</span>;

const ReadOnlyField = ({ label, value, children }) =>
<div style={{ minWidth: 0, marginBottom: 12 }}>
    <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(10.5), fontWeight: 650, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--ink-3)", marginBottom: 6 }}>{label}</div>
    <div style={{ minHeight: 40, display: "flex", alignItems: "center", gap: 7, flexWrap: "wrap", padding: "10px 11px", background: "color-mix(in srgb, var(--ink) 3%, var(--bg-2))", border: "1px solid var(--rule-2)", borderRadius: 10, color: "var(--ink)", fontFamily: "var(--f-display)", fontSize: typeSize(13.5), lineHeight: 1.35 }}>
      {children || value}
    </div>
  </div>;

const ReadOnlySection = ({ title, children }) =>
<div style={{ marginTop: 16 }}>
    <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(12), fontWeight: 700, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--ink-3)", marginBottom: 8 }}>{title}</div>
    {children}
  </div>;

const InvestorProfileForm = ({ nav }) => {
  const p = INVESTOR_PROFILE;
  const chatUpdate = () => {
    if (!nav) return;
    nav.ask("Update my investor profile.", "Of course. Tell me what changed about your goals, risk comfort, time horizon, liquidity needs, income, net worth, tax picture, investing experience, constraints, or special considerations. I'll update the profile from the conversation and ask you to confirm anything material.");
  };
  return (
    <div data-investor-profile-readonly="true" style={{ padding: "4px 16px 18px" }}>
      <div style={{ display: "flex", alignItems: "baseline", gap: 10, marginBottom: 14 }}>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(15), fontWeight: 650, letterSpacing: "-0.01em" }}>Yoshi's view of your investor profile</div>
          <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11.5), color: "var(--ink-3)", marginTop: 4, lineHeight: 1.45 }}>Built from conversations with Yoshi. Changes happen through chat, not this settings form.</div>
        </div>
        <ReadOnlyPill tone="accent">{p.status}</ReadOnlyPill>
      </div>

      <div style={{ border: "1px solid var(--rule-2)", borderRadius: 12, overflow: "hidden", background: "var(--bg-card)" }}>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(3, minmax(0, 1fr))", borderBottom: "1px solid var(--rule)" }}>
          {[
            ["Source", p.source],
            ["Profile version", p.version],
            ["Attested", p.attested]
          ].map(([label, value], i) => (
            <div key={label} style={{ padding: "11px 12px", borderLeft: i === 0 ? "none" : "1px solid var(--rule)" }}>
              <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(10), fontWeight: 650, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--ink-3)" }}>{label}</div>
              <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(13), fontWeight: 600, color: "var(--ink)", marginTop: 4 }}>{value}</div>
            </div>
          ))}
        </div>
        <div style={{ padding: "12px", display: "flex", alignItems: "center", gap: 10 }}>
          <Icon name="shield" size={18} color="var(--accent)" stroke={1.6} />
          <div style={{ flex: 1, minWidth: 0, fontFamily: "var(--f-display)", fontSize: typeSize(12.5), color: "var(--ink-2)", lineHeight: 1.45 }}>
            This is the profile Yoshi uses for suitability and advice context.
          </div>
        </div>
      </div>

      <ReadOnlySection title="Core profile">
      <PTwo>
          <ReadOnlyField label="Risk tolerance" value={p.risk} />
          <ReadOnlyField label="Time horizon" value={p.horizon} />
      </PTwo>
      <PTwo>
          <ReadOnlyField label="Objectives">
            {p.objectives.map((x) => <ReadOnlyPill key={x}>{x}</ReadOnlyPill>)}
          </ReadOnlyField>
          <ReadOnlyField label="Liquidity needs" value={p.liquidity} />
      </PTwo>
      </ReadOnlySection>

      <ReadOnlySection title="Financial picture">
      <PTwo>
          <ReadOnlyField label="Annual income band" value={p.income} />
          <ReadOnlyField label="Liquid net worth" value={p.liquid} />
      </PTwo>
      <PTwo>
          <ReadOnlyField label="Total net worth" value={p.netWorth} />
          <ReadOnlyField label="Tax status" value={p.tax} />
      </PTwo>
      <PTwo>
          <ReadOnlyField label="Investment experience" value={p.experience} />
          <ReadOnlyField label="Employment" value={p.employment} />
      </PTwo>
      </ReadOnlySection>

      <ReadOnlySection title="Facts Yoshi confirmed">
        <div style={{ border: "1px solid var(--rule-2)", borderRadius: 12, overflow: "hidden" }}>
          {p.facts.map((fact, i) => (
            <div key={fact} style={{ display: "grid", gridTemplateColumns: "18px minmax(0, 1fr)", gap: 9, padding: "12px 13px", borderBottom: i === p.facts.length - 1 ? "none" : "1px solid var(--rule)" }}>
              <Icon name="check" size={15} color="var(--accent)" stroke={2.1} />
              <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(12.5), color: "var(--ink-2)", lineHeight: 1.5 }}>{fact}</div>
            </div>
          ))}
        </div>
      </ReadOnlySection>

      <ReadOnlySection title="Constraints and considerations">
        <div style={{ border: "1px solid var(--rule-2)", borderRadius: 12, overflow: "hidden" }}>
          <div style={{ padding: "12px 13px", borderBottom: "1px solid var(--rule)" }}>
            <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11), color: "var(--ink-3)", marginBottom: 5 }}>Large planned expense</div>
            <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(13), color: "var(--ink)", lineHeight: 1.45 }}>{p.expenses[0].description} · {p.expenses[0].amount} in {p.expenses[0].timeframe}</div>
          </div>
          <div style={{ padding: "12px 13px", borderBottom: "1px solid var(--rule)" }}>
            <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11), color: "var(--ink-3)", marginBottom: 5 }}>Investment constraints</div>
            <div style={{ display: "flex", gap: 7, flexWrap: "wrap" }}>{p.constraints.map((x) => <ReadOnlyPill key={x}>{x}</ReadOnlyPill>)}</div>
          </div>
          <div style={{ padding: "12px 13px" }}>
            <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11), color: "var(--ink-3)", marginBottom: 5 }}>Special considerations</div>
            <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(13), color: "var(--ink-2)", lineHeight: 1.45 }}>{p.considerations}</div>
          </div>
        </div>
      </ReadOnlySection>

      <div data-investor-profile-chat-cta="text-width" style={{ marginTop: 14, display: "flex", justifyContent: "center" }}>
        <Btn onClick={chatUpdate}>Chat with Yoshi to update</Btn>
      </div>
    </div>);

};

/* ============ SETTINGS — its own screen, collapsible sections. On web it
   renders as a page beside the menu drawer (like the Agents pane); on mobile
   it pushes over the You hub. ============ */
/* ---- settings section bodies, each self-contained so it can render either as
   an accordion (mobile) or as a focused pane beside the drawer (web) ---- */
const NotificationsSettings = () => {
  const [channels, setChannels] = useState(PROFILE.channels.map((c) => c[2]));
  const [emailNotif, setEmailNotif] = useState(true);
  return (
    <>
      {PROFILE.channels.map(([name, detail], i) => {
      const web = window.__YOSHI_WEB && i === 0;
      return <SettingRow key={name} label={web ? "Browser notifications" : name} sub={web ? "This browser" : detail}
      right={<Toggle on={channels[i]} onChange={(v) => setChannels((c) => c.map((x, j) => j === i ? v : x))} />} />;
      })}
      <SettingRow label="Email notifications" sub="Briefs and confirmations to your inbox" last right={<Toggle on={emailNotif} onChange={setEmailNotif} />} />
    </>
  );
};

const PasskeyRecoveryPanel = ({ step, onCancel, onPlaidSuccess, onGenerated, onDone }) => {
  const [busy, setBusy] = useState(false);
  const run = (next) => {
    if (busy) return;
    setBusy(true);
    setTimeout(() => { setBusy(false); next(); }, 900);
  };
  const plaid = step === "plaid";
  const done = step === "done";
  return (
    <div className="push-enter" style={{ padding: "16px", minHeight: 360 }}>
      <div style={{ border: "1px solid var(--rule-2)", background: "var(--bg-card)", borderRadius: 12, padding: 18 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 16 }}>
          <div style={{ width: 40, height: 40, border: `1px solid ${plaid ? "#12a87c" : "var(--rule-2)"}`, borderRadius: 12, display: "grid", placeItems: "center", color: plaid ? "#12a87c" : "var(--accent)" }}>
            <Icon name={plaid ? "eye" : done ? "check" : "key"} size={22} stroke={1.6} />
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <Eyebrow color={plaid ? "#12a87c" : "var(--accent)"}>{plaid ? "Plaid identity" : done ? "Recovered" : "Yoshi passkey"}</Eyebrow>
            <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(20), fontWeight: 650, letterSpacing: "-0.02em", marginTop: 3 }}>
              {plaid ? "Liveness check" : done ? "New passkey ready" : "Generate new passkey"}
            </div>
          </div>
          {!done && <StatusTag tone="neutral">Required</StatusTag>}
        </div>

        <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(13), color: "var(--ink-2)", lineHeight: 1.55 }}>
          {plaid
            ? "Verify it's you with Plaid, then you'll return to Yoshi to create a new passkey."
            : done
              ? "This device now has a new passkey. Your previous device passkeys stay active unless you remove them."
              : "Plaid confirmed it's you. Create a new passkey in Yoshi."}
        </div>

        <div style={{ display: "grid", gap: 9, marginTop: 18 }}>
          {plaid && <Btn full onClick={() => run(onPlaidSuccess)} disabled={busy}>{busy ? "Checking…" : "Complete liveness check"}</Btn>}
          {step === "generate" && <Btn full onClick={() => run(onGenerated)} disabled={busy}>{busy ? "Generating…" : "Generate new passkey"}</Btn>}
          {done && <Btn full onClick={onDone}>Done</Btn>}
          {!done && <Btn kind="ghost" full onClick={onCancel} disabled={busy}>Back to security</Btn>}
        </div>
      </div>
    </div>
  );
};

const SecuritySettings = () => {
  const [recoveryStep, setRecoveryStep] = useState(null);
  if (recoveryStep) {
    return (
      <PasskeyRecoveryPanel
        step={recoveryStep}
        onCancel={() => setRecoveryStep(null)}
        onPlaidSuccess={() => setRecoveryStep("generate")}
        onGenerated={() => setRecoveryStep("done")}
        onDone={() => setRecoveryStep(null)}
      />
    );
  }
  return (
    <>
      <SettingRow label="Passkeys" sub="2 devices enrolled"
      right={<Btn kind="ghost" onClick={() => setRecoveryStep("plaid")} style={{ padding: "8px 13px", fontSize: typeSize(12), whiteSpace: "nowrap" }}>Recover passkey</Btn>} />
      <SettingRow label="Google sign-in" sub="Manage the Google account and email used to sign in to Yoshi" last
      right={<Btn kind="ghost" onClick={() => {}} style={{ padding: "8px 13px", fontSize: typeSize(12), whiteSpace: "nowrap" }}>Change</Btn>} />
    </>
  );
};

const AppearanceSettings = ({ palette, setPalette }) => (
  <div style={{ padding: "4px 16px 16px" }}>
    <div style={{ display: "flex", alignItems: "center", marginBottom: 11 }}>
      <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(14), fontWeight: 500 }}>Theme</span>
      <span style={{ marginLeft: "auto", fontFamily: "var(--f-display)", fontSize: typeSize(11.5), color: "var(--ink-3)" }}>{palette === "graphite" ? "Graphite · dark" : "Bone · light"}</span>
    </div>
    <Segmented options={[{ value: "graphite", label: "Dark" }, { value: "bone", label: "Light" }]} value={palette} onChange={setPalette} />
  </div>
);

const AutomationsSettings = () => {
  const [dailyCap, setDailyCap] = useState(5000);
  const [pendingCap, setPendingCap] = useState(5000);
  const [autoOn, setAutoOn] = useState(true);
  return (
    <>
      <SettingRow label="Automations active" sub={autoOn ? "Standing rules run inside your limits" : "All standing rules are paused"} right={<Toggle on={autoOn} onChange={setAutoOn} />} />
      <div style={{ padding: "2px 16px 16px", opacity: autoOn ? 1 : 0.45, pointerEvents: autoOn ? "auto" : "none", transition: "opacity .15s" }}>
        <div style={{ display: "flex", alignItems: "baseline", gap: 8 }}>
          <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(14), fontWeight: 500 }}>Daily autonomous cap</span>
          <span style={{ marginLeft: "auto", fontFamily: "var(--f-mono)", fontSize: typeSize(15), fontWeight: 500, color: "var(--accent)", fontVariantNumeric: "tabular-nums" }}>{usd(pendingCap, 0)}</span>
        </div>
        <input className="yo-range" type="range" min={0} max={25000} step={500} value={pendingCap}
        onChange={(e) => setPendingCap(parseInt(e.target.value, 10))} style={{ marginTop: 11 }} />
        <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(11), color: "var(--ink-3)", marginTop: 7, lineHeight: 1.45 }}>
          The most your agents can move in a day without asking. Per-automation limits are set on each proposal.
        </div>
        {pendingCap !== dailyCap &&
        <div style={{ marginTop: 13 }}><HoldButton label="Tap & hold to confirm" onConfirm={() => setDailyCap(pendingCap)} /></div>
        }
      </div>
    </>
  );
};

/* the section catalog — order matters; shared by the mobile screen, the web
   drawer list, and the web focused pane */
const settingsSections = (palette, setPalette, nav) => [
  { id: "personal", icon: "profile", label: "Personal information", sub: "Contact details and trusted contact", body: <PersonalInfoForm /> },
  { id: "investor", icon: "doc", label: "Investor profile", sub: "Suitability and advisory state", body: <InvestorProfileForm nav={nav} /> },
  { id: "notifications", icon: "bell", label: "Notifications", sub: "How Yoshi reaches you", body: <NotificationsSettings /> },
  { id: "security", icon: "shield", label: "Security", sub: "Passkeys and sign-in", body: <SecuritySettings /> },
  { id: "appearance", icon: "display", label: "Appearance", sub: "Theme and palette", body: <AppearanceSettings palette={palette} setPalette={setPalette} /> },
  { id: "automations", icon: "gear", label: "Automations", sub: "Daily autonomous cap", tag: "Soon", body: <AutomationsSettings /> },
  { id: "hidden", icon: "eye", label: "Hidden accounts", sub: "Accounts kept out of your totals", body: <HiddenAccounts /> },
  { id: "close", icon: "shield", label: "Close accounts", sub: "Permanently close an account", body: <CloseAccounts /> },
];

/* mobile: the full settings screen, sections as accordions */
const SettingsScreen = ({ palette, setPalette, nav, onClose }) => (
  <div className="push-enter" style={{ position: "absolute", inset: 0, zIndex: 40, background: "var(--bg)", display: "flex", flexDirection: "column" }} data-screen-label="Settings">
    <NavBar title="Settings" onBack={onClose} />
    <div className="scroll" style={{ paddingBottom: 24 }}>
      <div style={{ borderTop: "1px solid var(--rule)" }}>
        {settingsSections(palette, setPalette, nav).map((s, i, arr) => (
          <Accordion key={s.id} icon={s.icon} label={s.label} sub={s.sub} tag={s.tag} last={i === arr.length - 1}>{s.body}</Accordion>
        ))}
      </div>
    </div>
  </div>
);
window.SettingsScreen = SettingsScreen;

/* web: the drawer's settings list — replaces the menu contents; each row opens
   its section as a focused pane beside the drawer */
const SettingsList = ({ palette, setPalette, nav, onBack, onOpen }) => (
  <div style={{ flex: 1, display: "flex", flexDirection: "column", minHeight: 0 }}>
    <div style={{ flex: "none", height: 58, display: "flex", alignItems: "center", gap: 4, padding: "0 22px 0 10px", borderBottom: "1px solid var(--rule)" }}>
      <button className="press" aria-label="Back" title="Back" onClick={onBack} style={{ width: 38, height: 38, flex: "none", borderRadius: 10, display: "grid", placeItems: "center", background: "none", border: "none", color: "var(--ink)", cursor: "pointer" }}>
        <Icon name="back" size={22} />
      </button>
      <span style={{ fontFamily: "var(--f-display)", fontSize: typeSize(20), fontWeight: 600, letterSpacing: "-0.02em" }}>Settings</span>
    </div>
    <div className="scroll" style={{ paddingBottom: 24 }}>
      <div style={{ borderTop: "1px solid var(--rule)" }}>
        {settingsSections(palette, setPalette, nav).map((s, i, arr) => (
          <MenuRow key={s.id} icon={s.icon} label={s.label} sub={s.sub} onClick={() => onOpen(s.id)} last={i === arr.length - 1} />
        ))}
      </div>
    </div>
  </div>
);
window.SettingsList = SettingsList;

/* web: a single settings section, rendered as a focused pane beside the drawer */
const SettingsSectionPane = ({ id, palette, setPalette, nav, onClose }) => {
  const sec = settingsSections(palette, setPalette, nav).find((s) => s.id === id);
  if (!sec) return null;
  return (
    <div className="push-enter" style={{ position: "absolute", inset: 0, background: "var(--bg)", display: "flex", flexDirection: "column" }} data-screen-label="Settings section">
      <NavBar title={sec.label} />
      <div className="scroll" style={{ paddingBottom: 24 }}>
        <div style={{ borderTop: "1px solid var(--rule)" }}>{sec.body}</div>
      </div>
    </div>
  );
};
window.SettingsSectionPane = SettingsSectionPane;

const Profile = ({ palette, setPalette, nav, onClose }) => {
  const [view, setView] = useState("menu");
  const openBrokerage = () => nav.openAccount("brokerage");
  const openPaper = () => nav.openAccount("paper");
  if (view === "settings") {
    return window.__YOSHI_WEB
      ? <SettingsList palette={palette} setPalette={setPalette} nav={nav} onBack={() => { setView("menu"); nav.menuPage(null); }} onOpen={(id) => nav.menuPage("settings:" + id)} />
      : <SettingsScreen palette={palette} setPalette={setPalette} nav={nav} onClose={() => setView("menu")} />;
  }
  return (
    <div style={{ flex: 1, display: "flex", flexDirection: "column", minHeight: 0 }}>
      {window.__YOSHI_WEB ? (
        /* drawer header: an X aligned to the top-left hamburger it pulled out from */
        <div style={{ flex: "none", height: 58, display: "flex", alignItems: "center", padding: "0 22px 0 14px" }}>
          <button className="press" aria-label="Close menu" title="Close" onClick={() => (onClose ? onClose() : nav.tab("home"))} style={{ width: 38, height: 38, flex: "none", borderRadius: 10, display: "grid", placeItems: "center", background: "none", border: "none", color: "var(--ink)", cursor: "pointer" }}>
            <Icon name="close" size={22} />
          </button>
        </div>
      ) : (
        <NavBar title="You" border={false} onBack={() => nav.tab("home")} />
      )}
      <div className="scroll" style={{ paddingBottom: 24 }}>
        {/* identity */}
        <div style={{ padding: "0 16px 16px", display: "flex", alignItems: "center", gap: 14 }}>
          <div style={{ width: 56, height: 56, borderRadius: 999, background: "var(--accent)", color: "var(--accent-ink)", display: "grid", placeItems: "center", fontFamily: "var(--f-display)", fontSize: typeSize(22), fontWeight: 600 }}>RL</div>
          <div style={{ flex: 1 }}>
            <div style={{ fontFamily: "var(--f-display)", fontSize: typeSize(20), fontWeight: 600, letterSpacing: "-0.02em" }}>{PROFILE.name}</div>
          </div>
        </div>

        <div style={{ borderTop: "1px solid var(--rule)" }}>
          <MenuRow icon="accounts" label="Connect an external account" sub="Link a bank or brokerage, read-only" onClick={() => nav.sheet({ type: "link" })} />
          <MenuRow icon="easel" label="Connect an external agent" sub="Bring Yoshi to Claude, ChatGPT, or your own agent" onClick={() => nav.sheet({ type: "connect" })} />

          {/* open a new account — surfaced directly in the menu */}
          <MenuRow icon="plus" label="Open a Brokerage account" sub="Taxable investing across stocks and ETFs" onClick={openBrokerage} />
          <MenuRow icon="trade" label="Open a Paper trading account" sub="Practice with $100,000.00 in virtual funds" onClick={openPaper} />
          <MenuRow icon="gear" label="Settings" sub="Automations, channels, security, appearance" onClick={() => setView("settings")} />
          <MenuRow icon="doc" label="Documents" sub="Statements, tax forms, agreements" onClick={() => (window.__YOSHI_WEB ? nav.menuPage("documents") : nav.sheet({ type: "documents" }))} />
          <MenuRow icon="lifebuoy" label="Support" sub="Chat with Fin, our support assistant" onClick={() => nav.sheet({ type: "support" })} last />
        </div>

        <div style={{ padding: "8px 16px 0" }}>
          <Btn kind="ghost" full onClick={() => nav.signOut()}>Sign out</Btn>
        </div>
      </div>
    </div>);

};

window.Profile = Profile;
