;(function () {
/* WalletScreen — three-section vertical stack below the PageHeader.
   1. Balance hero  — full-bleed SVG (wallet-header.svg) carries the gradient
      card, "Total Available Funds" label + eye-off, action pills row, black
      CTA bar, and the F2F4F7 base strip. The dollar value is overlaid as
      live Text so it can be data-bound. Three invisible Pressables sit on
      top of the action pill regions for tap targets.
   2. Accounts  — full-bleed SVG (wallet-accounts.svg) carries the
      translucent container, inset shadow, section label, five overlapping
      rounded-top white card rectangles, and the bottom shadow strip. We
      overlay 5 rows of dynamic content (gradient-backed icon + label + value
      OR "Activate" pill) at fixed y-positions on each card. */

/* Home-page service-tile illustrations — reused as account-row icons. */
const IlloLeveraged = 'superapp/img/illo-leveraged.png';
const IlloGold      = 'superapp/img/illo-gold.png';
const IlloWealth    = 'superapp/img/illo-wealth.png';
const IlloShares    = 'superapp/img/illo-shares.png';

/* Inline JSX SVG icon components — replace RN's react-native-svg loader.
   ArrowDownRight / ArrowUpRight / PiggyBank are recoloured at runtime via
   their `color` prop (mapped onto stroke). */
const ArrowDownRight = ({ width = 24, height = 24, color = '#000' }) => (
  <svg width={width} height={height} viewBox="0 0 24 24" fill="none">
    <path d="M7 7l10 10 M17 7v10H7" stroke={color} strokeWidth={2} strokeLinecap="round" strokeLinejoin="round"/>
  </svg>
);

const ArrowUpRight = ({ width = 24, height = 24, color = '#000' }) => (
  <svg width={width} height={height} viewBox="0 0 24 24" fill="none">
    <path d="M7 17L17 7 M7 7h10v10" stroke={color} strokeWidth={2} strokeLinecap="round" strokeLinejoin="round"/>
  </svg>
);

const PiggyBank = ({ width = 24, height = 24, color = '#344054' }) => (
  <svg width={width} height={height} viewBox="0 0 24 24" fill="none">
    <path d="M4.99993 13C4.99993 9.68629 7.68622 7 10.9999 7M4.99993 13C4.99993 14.6484 5.66466 16.1415 6.74067 17.226C6.84445 17.3305 6.89633 17.3828 6.92696 17.4331C6.95619 17.4811 6.9732 17.5224 6.98625 17.5771C6.99993 17.6343 6.99993 17.6995 6.99993 17.8298V20.2C6.99993 20.48 6.99993 20.62 7.05443 20.727C7.10236 20.8211 7.17885 20.8976 7.27293 20.9455C7.37989 21 7.5199 21 7.79993 21H9.69993C9.97996 21 10.12 21 10.2269 20.9455C10.321 20.8976 10.3975 20.8211 10.4454 20.727C10.4999 20.62 10.4999 20.48 10.4999 20.2V19.8C10.4999 19.52 10.4999 19.38 10.5544 19.273C10.6024 19.1789 10.6789 19.1024 10.7729 19.0545C10.8799 19 11.0199 19 11.2999 19H12.6999C12.98 19 13.12 19 13.2269 19.0545C13.321 19.1024 13.3975 19.1789 13.4454 19.273C13.4999 19.38 13.4999 19.52 13.4999 19.8V20.2C13.4999 20.48 13.4999 20.62 13.5544 20.727C13.6024 20.8211 13.6789 20.8976 13.7729 20.9455C13.8799 21 14.0199 21 14.2999 21H16.2C16.48 21 16.62 21 16.727 20.9455C16.8211 20.8976 16.8976 20.8211 16.9455 20.727C17 20.62 17 20.48 17 20.2V19.2243C17 19.0223 17 18.9212 17.0288 18.8401C17.0563 18.7624 17.0911 18.708 17.15 18.6502C17.2114 18.59 17.3155 18.5417 17.5237 18.445C18.5059 17.989 19.344 17.2751 19.9511 16.3902C20.0579 16.2346 20.1112 16.1568 20.1683 16.1108C20.2228 16.0668 20.2717 16.0411 20.3387 16.021C20.4089 16 20.4922 16 20.6587 16H21.2C21.48 16 21.62 16 21.727 15.9455C21.8211 15.8976 21.8976 15.8211 21.9455 15.727C22 15.62 22 15.48 22 15.2V11.7857C22 11.5192 22 11.3859 21.9505 11.283C21.9013 11.181 21.819 11.0987 21.717 11.0495C21.6141 11 21.4808 11 21.2143 11C21.0213 11 20.9248 11 20.8471 10.9738C20.7633 10.9456 20.7045 10.908 20.6437 10.8438C20.5874 10.7842 20.5413 10.6846 20.4493 10.4855C20.1538 9.84622 19.7492 9.26777 19.2593 8.77404C19.1555 8.66945 19.1036 8.61716 19.073 8.56687C19.0437 8.51889 19.0267 8.47759 19.0137 8.42294C19 8.36567 19 8.30051 19 8.17018V7.06058C19 6.70053 19 6.52051 18.925 6.39951C18.8593 6.29351 18.7564 6.21588 18.6365 6.18184C18.4995 6.14299 18.3264 6.19245 17.9802 6.29136L15.6077 6.96922C15.5673 6.98074 15.5472 6.9865 15.5267 6.99054C15.5085 6.99414 15.4901 6.99671 15.4716 6.99826C15.4508 7 15.4297 7 15.3874 7H10.9999M4.99993 13H4C2.89543 13 2 12.1046 2 11C2 10.2597 2.4022 9.61337 3 9.26756M10.9999 7H14.9646C14.9879 6.8367 15 6.66976 15 6.5C15 4.567 13.433 3 11.5 3C9.567 3 8 4.567 8 6.5C8 6.9172 8.073 7.31736 8.20692 7.68839C9.04114 7.24881 9.99144 7 10.9999 7Z" stroke={color} strokeWidth={1.25} strokeLinecap="round" strokeLinejoin="round"/>
  </svg>
);

/* ───────── data ───────── */

/* Five business-unit rows. Amount/fraction are derived dynamically from
   the central `data/portfolio.js` module so any changes there (including
   a demo deposit) propagate here automatically. Cards 1-4 use the
   home-page service-tile illustrations; card 5 (Savings) is a CTA row
   with an "Activate" pill instead of a value. */
const ACCOUNTS = [
  { id: 'trading', label: 'Trading', illo: IlloLeveraged, ...formatAmount(getBalance('trading')), currency: 'USD' },
  { id: 'gold',    label: 'Gold',    illo: IlloGold,      ...formatAmount(getBalance('gold')),    currency: 'USD' },
  { id: 'wealth',  label: 'Wealth',  illo: IlloWealth,    ...formatAmount(getBalance('wealth')),  currency: 'USD' },
  { id: 'shares',  label: 'Shares',  illo: IlloShares,    ...formatAmount(getBalance('shares')),  currency: 'USD' },
  { id: 'savings', label: 'Savings', icon: PiggyBank, sub: 'Earn upto 6% yearly interest', action: 'Activate' },
];

const TRANSACTIONS = [
  /* Each row carries:
       kind     — picks the card icon (in|out|transfer|trade)
       status   — picks the state icon (success|pending|failed)
       title    — short verb-phrase label
       meta     — timestamp only; the source/destination lives in the pill
       amount   — raw number; the renderer splits into whole + fraction
       direction — 'to' (inflow) or 'from' (outflow); used for the pill
       account  — the business line the cash moves into / out of
     Times align with the trade activity feed where applicable:
       Added money (Visa) ↔ activity a3 (Today 05:50)
       Trade close (TSLA) ↔ activity a4 (Yesterday) */
  { id: 't1', kind: 'in',       status: 'success', title: 'Added money',  meta: 'Today · 05:50 AM',     amount: 5000.00,  direction: 'to',   account: 'Trading' },
  { id: 't2', kind: 'transfer', status: 'success', title: 'Transfer',     meta: 'Today · 04:18 AM',     amount: 3000.00,  direction: 'from', account: 'Trading' },
  { id: 't3', kind: 'trade',    status: 'success', title: 'Trade close',  meta: 'Yesterday · 02:45 PM', amount: 1070.00,  direction: 'from', account: 'Trading' },
  { id: 't4', kind: 'in',       status: 'success', title: 'Bonus credit', meta: 'May 8 · 10:00 AM',     amount: 300.00,   direction: 'to',   account: 'Trading' },
];

/* Expose for the voice agent's get_recent_transactions tool. */
window.WALLET_TRANSACTIONS = TRANSACTIONS;

/* ───────── tiny inline glyph (no chevron in the asset library) ───────── */

const ChevronRight = ({ size = 16, color = '#fff', stroke = 1.5 }) => (
  <svg width={size} height={size} viewBox="0 0 16 16" fill="none">
    <path d="M6 4l4 4-4 4" stroke={color} strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"/>
  </svg>
);

/* ───────── balance hero (SVG-driven) ─────────
   The Figma-exported header SVG is laid out in a 393×277 viewBox — every
   visual element is baked in (gradient card, label, eye-off, action pills
   with their own icons + labels, black CTA bar, F2F4F7 base strip). We only
   overlay the live dollar value (so it's data-bound) and three transparent
   Pressables on the action-pill rectangles to capture taps.

   Coordinate convention: SVG units map 1:1 to a 393-wide layout. We scale
   everything by `s = W / 393` so the overlay tracks the SVG on every device
   width. */
const HEADER_VB_W = 393;
const HEADER_VB_H = 277;

/* Card-coord positions (SVG units), measured against the source SVG paths.
   - Value row sits inside Content (padding 16) which sits inside Wrap
     (padding 8): x = 8 + 16 = 24 (left edge inside the visible 377-wide card
     starting at SVG x=8).
   - Value row top: card padding 8 + content padding 16 + label-row 20 + 4 gap
     = 48. Glyph baselines hover ~y=86 in SVG space, so a `top: 48` container
     with a 36px line ends up reading right.
   - Action pills row: y=116 → 176 (60h). First pill x=32, each pill 101.67w
     with 12 gap horizontally. */
const VALUE_X = 32;
const VALUE_Y = 48;
const PILL_Y = 116;
const PILL_H = 60;
const PILL_W = 101.67;
const PILL_GAP = 12;
const PILL_X = 32;

function HeroHeader({ amount = '0', fraction = '.00', currency = 'USD', onAdd, onWithdraw, onMove }) {
  const W = DEVICE_WIDTH;
  const s = W / HEADER_VB_W;
  const H = HEADER_VB_H * s;

  return (
    <div style={{ width: `${W}px`, height: `${H}px`, position: 'relative' }}>
      <img src="superapp/img/wallet-header.svg" width={W} height={H} alt=""/>

      {/* Live dollar value — overlaid on the empty value-row slot in the SVG.
         Three Texts share a baseline-aligned row: large number, small
         decimal "fracture", currency tag. */}
      <div
        style={{
          position: 'absolute',
          left: `${VALUE_X * s}px`,
          top: `${VALUE_Y * s}px`,
          display: 'flex',
          flexDirection: 'row',
          alignItems: 'flex-end',
          pointerEvents: 'none',
        }}
      >
        <span
          style={{
            fontFamily: 'Gilroy',
            fontWeight: 600,
            fontSize: `${36 * s}px`,
            lineHeight: `${44 * s}px`,
            color: colors.ink,
            letterSpacing: '-0.5px',
          }}
        >
          {amount}
        </span>
        <span
          style={{
            fontFamily: 'Gilroy',
            fontWeight: 400,
            fontSize: `${18 * s}px`,
            lineHeight: `${32 * s}px`,
            color: colors.ink,
            marginLeft: `${2 * s}px`,
          }}
        >
          {fraction}
        </span>
        <span
          style={{
            fontFamily: 'Gilroy',
            fontWeight: 600,
            fontSize: `${20 * s}px`,
            lineHeight: `${36 * s}px`,
            color: colors.ink,
            marginLeft: `${6 * s}px`,
          }}
        >
          {currency}
        </span>
      </div>

      {/* Tap targets layered over the three action pills. The pills' visuals
         (icons + labels) are inside the SVG; these Pressables only catch
         touches. */}
      {[onAdd, onWithdraw, onMove].map((handler, i) => (
        <button
          key={i}
          onClick={handler}
          style={{
            border: 'none',
            background: 'transparent',
            padding: 0,
            margin: 0,
            cursor: 'pointer',
            font: 'inherit',
            color: 'inherit',
            textAlign: 'inherit',
            position: 'absolute',
            left: `${(PILL_X + i * (PILL_W + PILL_GAP)) * s}px`,
            top: `${PILL_Y * s}px`,
            width: `${PILL_W * s}px`,
            height: `${PILL_H * s}px`,
            borderRadius: `${12 * s}px`,
          }}
        />
      ))}
    </div>
  );
}

/* ───────── accounts section (layered) ─────────
   Built from primitives + a single SVG for the wavy bottom strip.
   The Figma export's drop-shadow filters don't render reliably in
   react-native-svg's filter chain, so the cards are rendered as plain
   RN Views (rounded-top rectangle + boxShadow) instead of SVGs — this
   gives us a visible drop shadow that actually paints.

   Visual stack:
     • Outer white wrapper with rounded TOP corners + soft outer shadow.
     • "Balance" section label (RN Text, padded 16/24 per CSS).
     • Five business-unit cards — each is 329×84 (Figma body dimensions)
       with rounded TOP corners, white fill, and a `0 0 6 rgba(0,0,0,0.15)`
       boxShadow. Subsequent cards have marginTop = -24 so body bottoms
       overlap by exactly 24px (Figma spec), creating the deck-of-cards
       effect — `zIndex: i` ensures later cards paint on top.
     • Bottom strip (account-base.svg) — 361×72 wavy-top + rounded-bottom
       SVG. Wrapper carries its own boxShadow so it reads as a discrete
       layer below the last card. */
const CARD_BODY_W = 329;
const CARD_BODY_H = 84;
/* Savings is rendered shorter than the rest. Body height 68*s means only
   8*s of savings is hidden behind the BG bar at the sides (down from 24
   in the original deck), keeps savings's visible portion above the bar at
   exactly 60*s (matching every other card's visible portion), and opens
   the smile-zone gap between savings.bottom and the wave middle dip to
   ~21*s. */
const SAVINGS_BODY_H = 68;
const CARD_INNER_PAD_X = 16;
const CARD_INNER_PAD_Y = 12;
const CARD_OVERLAP = 24;
const CONTAINER_PAD_X = 16; // matches the original `padding 0 16` on the accounts list

const BASE_VB_W = 361;
/* Was 72; grew to 92 because the SVG now reserves a 20-unit upward strip
   above the wavy top so its inner-shadow Gaussian blur has room to render
   without being cut off at the viewBox edge. The body silhouette itself is
   unchanged; the wavy top simply moved from y=10 to y=30 inside the SVG. */
const BASE_VB_H = 92;
const BASE_TOP_OFFSET = 20; // viewBox padding above the wavy top in SVG units


function AccountsSection({ accounts = ACCOUNTS, onPress }) {
  const deviceW = DEVICE_WIDTH;
  const W = deviceW - 32;            // 16px page gutter on each side
  const s = W / 361;                 // overall scale (Figma container = 361)
  const cardW = CARD_BODY_W * s;
  const cardH = CARD_BODY_H * s;
  const cardInsetX = CONTAINER_PAD_X * s;
  const cardOverlap = CARD_OVERLAP * s;

  const baseH = BASE_VB_H * (W / BASE_VB_W);
  /* BG wavy-top sides are at SVG y=30 (BASE_TOP_OFFSET 20 + 10 within the
     body region). Savings is now SAVINGS_BODY_H=68 tall, and we want only
     SAVINGS_BAR_OVERLAP=8 of it tucked behind the bar at sides — so the
     wavy sides land at savings.bottom-8, which means wrapper_top sits at
     savings.bottom-38. With inner_bottom = savings.bottom (no padding),
     baseOverlap = (8 + 30) * s = 38*s. (At MIDDLE the wavy curve dips
     down 28.67 below the sides, opening a clear ~21*s smile-zone gap
     between savings.bottom and the wave dip.) */
  const baseOverlap = (8 + 30) * s;

  return (
    <div style={{
      marginLeft: '16px',
      marginRight: '16px',
      marginTop: '16px',
      width: `${W}px`,
      /* Outer drop shadow on the entire balance-card box. Border radius
         scales with `s` so it tracks the SVG corner radius at any width.
         backgroundColor white fills the "smile zone" — the 4-28px gap at
         middle x between the savings card's bottom and the BG SVG's wavy
         top — that would otherwise show the grey page bg through BG's
         transparent area, reading as a shade difference. */
      backgroundColor: 'white',
      boxShadow: '0px 8px 24px rgba(14, 20, 32, 0.12)',
      borderRadius: `${20 * s}px`,
    }}>
      {/* Outer white surface with rounded TOP corners. Bottom corners are
         provided by the BG strip's own rounded-bottom path so they line up.
         Soft halo only — the inset top shadow was removed; the outer drop
         shadow on the wrapper above (this View's parent) carries the lift. */}
      <div style={{
        backgroundColor: 'white',
        borderTopLeftRadius: `${20 * s}px`,
        borderTopRightRadius: `${20 * s}px`,
        boxShadow: '0px 0px 10px rgba(0, 0, 0, 0.05)',
      }}>
        <div style={{
          paddingTop: '16px',
          paddingLeft: '24px',
          paddingRight: '24px',
          paddingBottom: '12px',
          fontFamily: 'Inter',
          fontWeight: 500,
          fontSize: '14px',
          lineHeight: '20px',
          color: '#475467',
        }}>
          Balance
        </div>

        {accounts.map((a, i) => {
          const isLast = i === accounts.length - 1;
          return (
            <div
              key={a.id}
              style={{
                position: 'relative',
                marginTop: i === 0 ? 0 : `${-cardOverlap}px`,
                marginLeft: `${cardInsetX}px`,
                marginRight: `${cardInsetX}px`,
                zIndex: i,
                width: `${cardW}px`,
                /* Savings is rendered shorter (SAVINGS_BODY_H instead of
                   CARD_BODY_H) so it doesn't extend deep behind the BG. */
                height: `${(isLast ? SAVINGS_BODY_H : CARD_BODY_H) * s}px`,
                backgroundColor: 'white',
                borderTopLeftRadius: `${20 * s}px`,
                borderTopRightRadius: `${20 * s}px`,
                /* Same upward halo on every card. Blur reduced from 8 → 6
                   (~25%) so the deck is softer and more in line with the
                   BG strip's curve-following halo. Negative spread (-2)
                   keeps the shadow's bottom anchored at the card edge so
                   it doesn't bleed below into the smile zone. */
                boxShadow: '0px -6px 6px -2px rgba(0, 0, 0, 0.22)',
              }}
            >
              {/* Row overlay fills the VISIBLE card area (60*s for cards
                 1-4, 84*s for the last) so we can use flex-center to
                 vertically align the icon/label/value content with the
                 visible card body. Per home-tile parity: labels in
                 Gilroy-SemiBold 16/20, no scaling. */}
              <button
                onClick={() => onPress?.(a)}
                style={{
                  border: 'none',
                  background: 'transparent',
                  padding: 0,
                  margin: 0,
                  cursor: 'pointer',
                  font: 'inherit',
                  color: 'inherit',
                  textAlign: 'inherit',
                  position: 'absolute',
                  left: `${CARD_INNER_PAD_X * s}px`,
                  top: 0,
                  right: `${CARD_INNER_PAD_X * s}px`,
                  /* Pressable height is the visible portion (60*s) for ALL
                     cards — including savings — so `alignItems:'center'`
                     puts content at y=30 from each card's top edge,
                     producing identical icon/label vertical positions
                     across the deck. */
                  height: `${(CARD_BODY_H - CARD_OVERLAP) * s}px`,
                  display: 'flex',
                  flexDirection: 'row',
                  alignItems: 'center',
                  justifyContent: 'space-between',
                }}
              >
                {/* Left: icon + label (or icon + label/sub stack on Savings).
                   All five rows render their icon at the EXACT home-tile
                   sizing (60×60 fixed with -9 margins) so visual weight and
                   stroke thickness match the home page. Savings now uses
                   the piggy-bank line icon directly (no gradient backdrop). */}
                <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: isLast ? '8px' : '4px' }}>
                  {a.illo ? (
                    <img
                      src={a.illo}
                      style={{
                        width: '60px',
                        height: '60px',
                        marginLeft: '-9px',
                        marginRight: '-9px',
                        marginTop: '-9px',
                        marginBottom: '-9px',
                        objectFit: 'contain',
                      }}
                      alt=""
                    />
                  ) : a.icon ? (
                    <div style={{
                      width: '60px',
                      height: '60px',
                      marginLeft: '-9px',
                      marginRight: '-9px',
                      marginTop: '-9px',
                      marginBottom: '-9px',
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                    }}>
                      {/* Slightly smaller (36 vs 42) and slimmer stroke
                         (1.25 in the SVG vs 1.5) so the line icon's optical
                         weight matches its label and isn't reading as bold. */}
                      <a.icon width={36} height={36} color={colors.ink2}/>
                    </div>
                  ) : null}
                  {isLast ? (
                    <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
                      <span style={{
                        fontFamily: 'Gilroy',
                        fontWeight: 600,
                        fontSize: '16px',
                        lineHeight: '20px',
                        color: colors.ink2,
                      }}>{a.label}</span>
                      <span style={{
                        fontFamily: 'Inter',
                        fontWeight: 400,
                        fontSize: '10px',
                        lineHeight: '14px',
                        color: colors.muted2,
                        marginTop: '1px',
                      }}>{a.sub}</span>
                    </div>
                  ) : (
                    <span style={{
                      fontFamily: 'Gilroy',
                      fontWeight: 600,
                      fontSize: '16px',
                      lineHeight: '20px',
                      color: colors.ink2,
                    }}>{a.label}</span>
                  )}
                </div>

                {/* Right: amount/fraction/currency triple, or Activate pill
                   on Savings. Activate uses Gilroy-SemiBold per design. */}
                {a.action ? (
                  <div style={{
                    backgroundColor: '#F2F2F2',
                    borderRadius: '31px',
                    paddingLeft: '16px',
                    paddingRight: '16px',
                    paddingTop: '8px',
                    paddingBottom: '8px',
                  }}>
                    <span style={{
                      fontFamily: 'Gilroy',
                      fontWeight: 600,
                      fontSize: '12px',
                      lineHeight: '18px',
                      color: colors.ink,
                    }}>{a.action}</span>
                  </div>
                ) : (
                  <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'flex-end' }}>
                    <span style={{
                      fontFamily: 'Gilroy',
                      fontWeight: 700,
                      fontSize: '16px',
                      lineHeight: '20px',
                      color: colors.ink2,
                    }}>{a.amount}</span>
                    <span style={{
                      fontFamily: 'Inter',
                      fontWeight: 400,
                      fontSize: '12px',
                      lineHeight: '18px',
                      color: colors.ink2,
                      marginLeft: '2px',
                    }}>{a.fraction}</span>
                    <span style={{
                      fontFamily: 'Inter',
                      fontWeight: 400,
                      fontSize: '12px',
                      lineHeight: '18px',
                      color: colors.ink2,
                      marginLeft: '2px',
                    }}>{a.currency}</span>
                  </div>
                )}
              </button>
            </div>
          );
        })}
      </div>

      {/* BG strip: wavy top peeks below the last card; rounded bottom
         corners seal the section.
         The depth between the savings card and the BG comes from TWO
         existing shadows: (a) the savings card's own `0 0 8 rgba(0,0,0,0.18)`
         halo, which casts onto the BG's transparent area in the smile zone,
         and (b) the BG's outer halo below. An inset top shadow on the
         wrapper would paint as a flat rectangular band that doesn't follow
         the wavy curve — so we don't use one.
         `borderBottomLeftRadius/Right: 20 * s` matches the SVG's own
         scaled corner radius at any device width; `overflow: 'hidden'`
         clips any stray rendering to that rounded-bottom silhouette. */}
      <div style={{
        /* CSS requires `position: relative` (or any positioning) for
           `z-index` to take effect — RN respects zIndex regardless. Without
           this the bottom strip would paint UNDER the savings card. */
        position: 'relative',
        marginTop: `${-baseOverlap}px`,
        zIndex: accounts.length,
        borderBottomLeftRadius: `${20 * s}px`,
        borderBottomRightRadius: `${20 * s}px`,
        overflow: 'hidden',
        /* Only the downward outer halo remains; the shadow above the wavy
           top is rendered inside the SVG via curve-following strokes so it
           dips with the wave instead of painting a straight band. */
        boxShadow: '0px 6px 14px rgba(14, 20, 32, 0.10)',
      }}>
        <img src="superapp/img/account-base.svg" width={W} height={baseH} alt=""/>
      </div>
    </div>
  );
}

/* ───────── transaction row ─────────
   Left column = vertical [card-icon, state-icon] stack pulled from the
   user-uploaded SVGs in superapp/icons/wallet/. The card-icon picks
   the right verb (download / upload / refresh) based on row.kind; the
   state-icon picks success / pending / failed based on row.status. */
const KIND_ICON = {
  in:       'superapp/icons/wallet/card-download.svg',
  out:      'superapp/icons/wallet/card-upload.svg',
  transfer: 'superapp/icons/wallet/card-refresh.svg',
  trade:    'superapp/icons/wallet/card-refresh.svg',
};

const STATE_ICON = {
  success: 'superapp/icons/wallet/state-success.svg',
  pending: 'superapp/icons/wallet/state-pending.svg',
  failed:  'superapp/icons/wallet/state-failed.svg',
};

/* Tiny "+" glyph as a 12×12 SVG icon — the Figma spec uses an icon
   here, not the literal "+" character. */
const PlusGlyph = ({ color = '#344054' }) => (
  <svg width={12} height={12} viewBox="0 0 12 12" fill="none">
    <path d="M6 2.5v7M2.5 6h7" stroke={color} strokeWidth={1} strokeLinecap="round" strokeLinejoin="round"/>
  </svg>
);

/* 3×3 grey divider dot used between the "Today" and "09:15 AM"
   timestamp halves. Spec calls for a 4×4 box with a 3×3 dot inside. */
const TimeDot = () => (
  <span style={{
    width: '4px', height: '4px',
    display: 'inline-block', position: 'relative',
  }}>
    <span style={{
      position: 'absolute',
      width: '3px', height: '3px',
      left: '0.5px', top: '0.5px',
      backgroundColor: '#D0D5DD',
      borderRadius: '1.5px',
    }}/>
  </span>
);

/* Split the row's `meta` ("Today · 09:15 AM") on the centre dot so we
   can render the explicit dot glyph between the two halves per spec. */
function splitMeta(meta) {
  if (!meta) return { left: '', right: '' };
  const parts = meta.split('·').map((s) => s.trim());
  if (parts.length < 2) return { left: meta, right: '' };
  return { left: parts[0], right: parts.slice(1).join(' · ') };
}

const TxRow = ({ t }) => {
  const status = t.status || 'success';
  const cardIcon = KIND_ICON[t.kind] || KIND_ICON.in;
  const stateIcon = STATE_ICON[status] || STATE_ICON.success;
  const parts = formatAmount(t.amount);
  /* "+" sign on every row regardless of direction — spec mock shows
     this. The To/From pill carries the directional semantics. */
  const meta = splitMeta(t.meta);
  const pillLabel = (t.direction === 'from' ? 'From ' : 'To ') + (t.account || 'Trading');
  return (
    <div style={styles.txRow}>
      <div style={styles.txIconStack}>
        <div style={styles.txCardIconWrap}>
          <img src={cardIcon} width={16} height={16} alt=""/>
        </div>
        <img src={stateIcon} width={20} height={20} alt="" style={styles.txStateIcon}/>
      </div>
      <div style={styles.txHead}>
        <div style={styles.txTitle}>{t.title}</div>
        <div style={styles.txTimeRow}>
          <span style={styles.txTimeLabel}>{meta.left}</span>
          {meta.right ? <TimeDot /> : null}
          {meta.right ? <span style={styles.txTimeLabel}>{meta.right}</span> : null}
        </div>
      </div>
      <div style={styles.txTail}>
        <div style={styles.txNumberRow}>
          <PlusGlyph />
          <span style={styles.txAmountValue}>{parts.amount}</span>
          <span style={styles.txAmountFraction}>{parts.fraction}</span>
          <span style={styles.txAmountCurrency}>USD</span>
        </div>
        <div style={styles.txChipRow}>
          <div style={styles.txAccountChip}>
            <span style={styles.txAccountChipText}>{pillLabel}</span>
          </div>
        </div>
      </div>
    </div>
  );
};

/* ───────── screen ───────── */

function WalletScreen({ active }) {
  /* When the user enters the wallet tab while a pending withdrawal
     exists, surface the "payment provider delay" notification. We
     fire only on transitions into active=true, not on every render
     while the tab is active, by gating on a ref. */
  const lastActiveRef = React.useRef(false);
  const pending = window.usePendingWithdrawals ? window.usePendingWithdrawals() : [];
  React.useEffect(() => {
    if (active && !lastActiveRef.current && pending.length > 0) {
      if (window.showCashFlowNotification) window.showCashFlowNotification('withdraw');
    }
    lastActiveRef.current = active;
  }, [active, pending.length]);

  const liveBalances = window.useBalances();
  const accountsLive = ACCOUNTS.map((a) => {
    if (a.id === 'savings') return a;
    const live = liveBalances[a.id];
    if (live == null) return a;
    return { ...a, ...formatAmount(live) };
  });
  const liveTotalValue = Object.values(liveBalances).reduce((a, b) => a + b, 0);
  const liveTotal = formatAmount(liveTotalValue);

  return (
    <div
      style={{ flex: 1, backgroundColor: colors.bg, overflowY: 'auto', WebkitOverflowScrolling: 'touch', scrollbarWidth: 'none', position: 'relative', width: '100%', height: '100%' }}
    >
      <div style={{ paddingBottom: '200px', backgroundColor: colors.bg, position: 'relative' }}>
        {/* Top overscroll cushion — matches white PageHeader on pull-down. */}
        <div
          style={{ position: 'absolute', top: '-1000px', left: 0, right: 0, height: '1000px', backgroundColor: '#fff', pointerEvents: 'none' }}
        />
        <PageHeader title="Wallet" center={<img src="design-system/assets/icons/usd-pill.svg" width={82} height={36} alt=""/>}/>

        {/* ─── 1. BALANCE HERO ──────────────────────────────────────────
           Total amount is computed from the shared portfolio data module so
           it always equals the sum of the per-account values shown below. */}
        <HeroHeader
          amount={liveTotal.amount}
          fraction={liveTotal.fraction}
          currency="USD"
          /* Three pills wire into the global cash-flow sheet via the
             App-level trigger. Add maps to deposit; Withdraw is its
             own thing; Move maps to transfer. */
          onAdd={() => window.openCashFlow && window.openCashFlow('deposit')}
          onWithdraw={() => window.openCashFlow && window.openCashFlow('withdraw')}
          onMove={() => window.openCashFlow && window.openCashFlow('transfer')}
        />

        {/* ─── 2. ACCOUNTS ────────────────────────────────────────────── */}
        <AccountsSection accounts={accountsLive}/>


        {/* ─── 3. TRANSACTIONS ─────────────────────────────────────────────
           Spec: 361×452 white card, borderRadius 20, harder shadow
           (0 4 4 rgba(0,0,0,0.25)). Section label header (52px tall,
           padding 16 24) over a list of activity cards (76px each)
           with inset hairline dividers between them. */}
        <div style={styles.cardWrap}>
          <div style={styles.cardSurface}>
            <div style={styles.txSectionHead}>
              <span style={styles.txSectionTitle}>Recent transactions</span>
              <button style={{ border: 'none', background: 'transparent', padding: 0, margin: 0, cursor: 'pointer', font: 'inherit', color: 'inherit', textAlign: 'inherit', ...styles.txViewAllRow }}>
                <span style={styles.txViewAllText}>View more</span>
                <ChevronRight size={14} color="#667085" stroke={1.5}/>
              </button>
            </div>
            <div style={styles.txList}>
              {[
                /* Live pending withdrawals from the trade-store. Prepend
                   them so they sit above the static demo transactions. */
                ...pending.map((p) => {
                  const accountLabel = ({ trading: 'Trading', gold: 'Gold', wealth: 'Wealth', shares: 'Cash Equities', savings: 'Savings' })[p.account] || 'Trading';
                  const reqDate = p.requestedAt ? new Date(p.requestedAt) : null;
                  const meta = reqDate
                    ? `Today · ${reqDate.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })}`
                    : 'Just now';
                  return { id: p.id, kind: 'out', status: 'pending', title: 'Withdrawal', meta, amount: p.amount, direction: 'from', account: accountLabel };
                }),
                ...TRANSACTIONS,
              ].map((t, i, arr) => (
                <React.Fragment key={t.id}>
                  <TxRow t={t}/>
                  {i < arr.length - 1 ? <div style={styles.txDivider}/> : null}
                </React.Fragment>
              ))}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ───────── styles ───────── */

const styles = {
  /* Card surface — Figma spec: 361 wide white card with the harder
     0 4 4 rgba(0,0,0,0.25) shadow. Zero padding here; the section
     header and the row list each carry their own padding. */
  cardWrap: { paddingLeft: '16px', paddingRight: '16px', marginTop: '16px' },
  cardSurface: {
    backgroundColor: '#fff',
    borderRadius: '20px',
    boxShadow: '0px 4px 4px rgba(0, 0, 0, 0.25)',
  },
  /* Section label header — 52px tall, padding 16 24, title left, action right. */
  txSectionHead: {
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingTop: '16px',
    paddingBottom: '16px',
    paddingLeft: '24px',
    paddingRight: '24px',
    height: '52px',
    boxSizing: 'border-box',
  },
  txSectionTitle: {
    fontFamily: 'Inter',
    fontWeight: 500,
    fontSize: '14px',
    lineHeight: '20px',
    color: '#475467',
  },
  txViewAllRow: {
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center',
    gap: '4px',
  },
  txViewAllText: {
    fontFamily: 'Inter',
    fontWeight: 400,
    fontSize: '12px',
    lineHeight: '18px',
    color: '#667085',
  },
  /* Row list — padding 0 16 16 per spec, dividers inset 8 each side. */
  txList: {
    paddingLeft: '16px',
    paddingRight: '16px',
    paddingBottom: '16px',
    display: 'flex',
    flexDirection: 'column',
  },
  /* Each transaction — 76px tall, padding 16 16 16 12, 4-gap row. */
  txRow: {
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center',
    gap: '4px',
    height: '76px',
    paddingTop: '16px',
    paddingRight: '16px',
    paddingBottom: '16px',
    paddingLeft: '12px',
    boxSizing: 'border-box',
  },
  /* Divider between rows — 304px hairline inset 8px each side. */
  txDivider: {
    height: '1px',
    backgroundColor: '#EAECF0',
    marginLeft: '8px',
    marginRight: '8px',
  },
  /* Left column — vertical [card-icon, state-icon] stack. The card
     icon is given a -8px vertical margin so it overlaps the holder's
     bounds, matching the Figma spec's compact stacking. */
  txIconStack: {
    width: '32px',
    height: '44px',
    flexShrink: 0,
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'center',
  },
  txCardIconWrap: {
    width: '32px',
    height: '32px',
    borderRadius: '31px',
    backgroundColor: '#fff',
    border: '1px solid #EAECF0',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
  },
  /* State icon sits under the card icon with a small overlap — its
     top edge laps onto the card's lower-right curve, matching the
     Figma reference. -6px gives the visible "lapping" without the
     state icon sitting on top of the card glyph. */
  txStateIcon: {
    display: 'block',
    marginTop: '-6px',
  },
  /* Head — title + timestamp column, 44 tall. */
  txHead: {
    flex: 1,
    minWidth: 0,
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'flex-start',
    height: '44px',
    paddingLeft: '4px',
  },
  txTitle: {
    fontFamily: 'Inter',
    fontWeight: 500,
    fontSize: '14px',
    lineHeight: '20px',
    color: '#101828',
  },
  txTimeRow: {
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center',
    flexWrap: 'nowrap',
    gap: '4px',
    height: '18px',
    marginTop: '6px',
  },
  txTimeLabel: {
    fontFamily: 'Inter',
    fontWeight: 400,
    fontSize: '12px',
    lineHeight: '18px',
    color: '#667085',
    whiteSpace: 'nowrap',
  },
  /* Tail — amount row + chip, right-aligned, 44 tall. */
  txTail: {
    width: '133px',
    height: '44px',
    flexShrink: 0,
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'flex-end',
  },
  /* Number row — plus icon + value (Gilroy 700 16) + fraction (Inter
     12) + currency (Inter 12). All in #344054. */
  txNumberRow: {
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center',
    gap: '2px',
    height: '20px',
    fontVariantNumeric: 'tabular-nums',
  },
  txAmountValue: {
    fontFamily: 'Gilroy',
    fontWeight: 700,
    fontSize: '16px',
    lineHeight: '20px',
    color: '#344054',
  },
  txAmountFraction: {
    fontFamily: 'Inter',
    fontWeight: 400,
    fontSize: '12px',
    lineHeight: '18px',
    color: '#344054',
  },
  txAmountCurrency: {
    fontFamily: 'Inter',
    fontWeight: 400,
    fontSize: '12px',
    lineHeight: '18px',
    color: '#344054',
  },
  /* Chip row — 18 tall, right-aligned. */
  txChipRow: {
    display: 'flex',
    flexDirection: 'row',
    justifyContent: 'flex-end',
    alignItems: 'center',
    gap: '4px',
    height: '18px',
    marginTop: '6px',
  },
  /* Source/destination chip — replaces old "TICKET" tag. Inter
     Medium 10/14 #344054 on a light grey #F9FAFB pill, 4px radius. */
  txAccountChip: {
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center',
    paddingTop: '2px',
    paddingBottom: '2px',
    paddingLeft: '6px',
    paddingRight: '6px',
    backgroundColor: '#F9FAFB',
    borderRadius: '4px',
  },
  txAccountChipText: {
    fontFamily: 'Inter',
    fontWeight: 500,
    fontSize: '10px',
    lineHeight: '14px',
    color: '#344054',
    textAlign: 'center',
  },
};

Object.assign(window, { WalletScreen });
})();
