// EVERSEAL — Main VC Flow · 4 tab ViewControllers
// Dashboard / Registration / Verification / My Page
// Built on the EverSeal iOS design system (tokens.css + components.css + icons.js)
// Grounded in 요구사항정의서 (EVS-iOS 004/005/007/010/013) + As-Is/To-Be 설계
// Exports screens + MainTabBar to window. Requires icons.js (esIcon) + ios-frame.jsx (IOSDevice)

const Ic = ({ n, s = 24, sw = 1.8, style }) => (
  <span style={{ display: 'inline-flex', ...style }}
        dangerouslySetInnerHTML={{ __html: esIcon(n, { size: s, sw }) }} />
);

// ── 지갑 주소: 가운데 …축약 · 1줄 고정 · 복사 + 복사 피드백 ──
function WalletAddr({ addr, head = 6, tail = 5, prefix = '지갑' }) {
  const [copied, setCopied] = React.useState(false);
  const short = addr.length > head + tail + 1
    ? addr.slice(0, head) + '…' + addr.slice(-tail)
    : addr;
  const copy = (e) => {
    e.stopPropagation();
    try { navigator.clipboard && navigator.clipboard.writeText(addr); } catch (_) {}
    setCopied(true);
    clearTimeout(copy._t);
    copy._t = setTimeout(() => setCopied(false), 1500);
  };
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 3, minWidth: 0 }}>
      <span className="es-caption es-ink-3 es-mono" style={{ whiteSpace: 'nowrap', flexShrink: 0 }}>
        {prefix ? prefix + ' ' : ''}{short}
      </span>
      <button type="button" onClick={copy} aria-label="지갑 주소 복사" style={{
        flexShrink: 0, display: 'inline-flex', alignItems: 'center', gap: 3,
        border: 'none', background: 'transparent', cursor: 'pointer', padding: '2px 3px',
        borderRadius: 6, fontFamily: 'inherit',
        color: copied ? 'var(--es-success)' : 'var(--es-ink-4)' }}>
        <Ic n={copied ? 'check' : 'doc'} s={14} />
        {copied && <span className="es-caption" style={{ color: 'var(--es-success)', fontWeight: 600 }}>복사됨</span>}
      </button>
    </div>
  );
}

// ── status-bar-safe in-screen nav bar ────────────────────
function MtNav({ title, left, right, large, sub, dark, accent }) {
  const titleColor = dark ? '#fff' : 'var(--es-ink)';
  return (
    <div style={{
      paddingTop: 50, flexShrink: 0,
      background: dark ? 'rgba(18,32,23,0.55)' : 'rgba(255,255,255,0.82)',
      backdropFilter: 'saturate(180%) blur(20px)', WebkitBackdropFilter: 'saturate(180%) blur(20px)',
      borderBottom: large ? 'none' : `0.5px solid ${dark ? 'rgba(255,255,255,0.12)' : 'var(--es-separator)'}`,
      position: 'relative', zIndex: 5,
    }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        gap: 12, padding: '6px 12px 8px', minHeight: 44 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 4, minWidth: 44 }}>{left}</div>
        {!large && <div className="es-headline" style={{ color: titleColor }}>{title}</div>}
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 44, justifyContent: 'flex-end' }}>{right}</div>
      </div>
      {large && (
        <div style={{ padding: '0 16px 12px' }}>
          {accent && <div className="es-caption-2" style={{ textTransform: 'uppercase', letterSpacing: '1.4px', color: 'var(--es-bronze)', fontWeight: 700, marginBottom: 4 }}>{accent}</div>}
          <div className="es-large-title" style={{ color: titleColor }}>{title}</div>
          {sub && <div className="es-subhead" style={{ color: dark ? 'rgba(255,255,255,0.6)' : 'var(--es-ink-2)', marginTop: 3 }}>{sub}</div>}
        </div>
      )}
    </div>
  );
}

const NavIcon = ({ n, s = 22, onClick, dark }) => (
  <button className="es-navbar__btn" onClick={onClick}
    style={{ color: dark ? '#fff' : 'var(--es-ink)' }}>
    <Ic n={n} s={s} />
  </button>
);

const Scroll = ({ children, style }) => (
  <div style={{ flex: 1, overflow: 'auto', WebkitOverflowScrolling: 'touch', ...style }}>{children}</div>
);

const Canvas = ({ from, to, h = 200, r, style, children, img }) => (
  <div style={{ height: h, background: img ? undefined : `linear-gradient(145deg, ${from}, ${to})`,
    position: 'relative', borderRadius: r, overflow: img ? 'hidden' : undefined, ...style }}>
    {img && <img src={img} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />}
    {children}
  </div>
);

const SealBadge = ({ label = '정품 인증', small }) => (
  <span className="es-badge es-badge--verified" style={small ? { padding: '3px 7px' } : null}>
    <Ic n="shield-check" s={small ? 11 : 12} />{!small && label}
  </span>
);

// trade-status pill
const TradeTag = ({ status }) => {
  const map = {
    '보관중': ['neutral', null],
    '거래중': ['info', null],
    '판매완료': ['success', null],
  };
  const [variant] = map[status] || ['neutral'];
  return <span className={`es-badge es-badge--${variant}`}>{status}</span>;
};

// ═════════════════════════════════════════════════════════
//  MAIN TAB BAR — 4 tabs
// ═════════════════════════════════════════════════════════
const TABS = [
  ['dashboard', '대시보드', 'home', 'home-fill'],
  ['register', '등록', 'plus', 'plus'],
  ['verify', '인증', 'shield-check', 'shield-fill'],
  ['my', '마이', 'person', 'person-fill'],
];

function MainTabBar({ active = 'dashboard', onChange }) {
  return (
    <nav className="es-tabbar" style={{ flexShrink: 0, paddingBottom: 26 }}>
      {TABS.map(([k, label, ic, fill]) => {
        const on = k === active;
        return (
          <button key={k} className={'es-tab' + (on ? ' es-tab--active' : '')}
            onClick={() => onChange && onChange(k)}>
            <Ic n={on ? (fill || ic) : ic} s={26} sw={1.8} />
            {label}
          </button>
        );
      })}
    </nav>
  );
}

// shared artwork palettes
const ART = {
  dawn:   ['#C9BBA0', '#7C6A48'],
  layers: ['#D8C2C0', '#7A5556'],
  moon:   ['#E7E2D6', '#A89B7C'],
  abyss:  ['#3A4A63', '#0E1726'],
  blue:   ['#9FB4C9', '#3C566E'],
};

// ═════════════════════════════════════════════════════════
//  TAB 1 — DASHBOARD  (보유작품 관리 · EVS-iOS 004)
// ═════════════════════════════════════════════════════════
function DashboardScreen({ active = 'dashboard', onTab }) {
  const [filter, setFilter] = React.useState('전체');
  const assets = [
    { t: '새벽의 정물 No.3', a: '박서린', ed: '12 / 50', nft: '#4821', trade: '보관중', pal: ART.dawn, img: 'assets/dawn-still-life.jpg' },
    { t: '겹의 시간', a: '한도윤', ed: '04 / 20', nft: '#5102', trade: '거래중', price: '2,100', pal: ART.layers },
    { t: '백자 달항아리', a: '오세진', ed: '01 / 01', nft: '#3380', trade: '보관중', pal: ART.moon },
    { t: '심해의 빛', a: '이정안', ed: '07 / 30', nft: '#2910', trade: '판매완료', pal: ART.abyss },
  ];
  const shown = filter === '전체' ? assets : assets.filter(x => x.trade === filter);

  // 내가 보유하지 않은 작품에 대해 판매자가 제시한 구매 오퍼 (XRPL Sell Offer)
  const buyOffers = [
    { t: '청록 변주', a: '김서진', ed: '09 / 25', nft: '#1740', price: '1,850', seller: '김서진', pal: ART.blue, img: 'assets/teal-variations.jpg' },
    { t: '겨울 창', a: '문지호', ed: '03 / 15', nft: '#0932', price: '3,050', seller: '문지호', pal: ART.dawn, img: 'assets/winter-window.jpg' },
  ];
  // 내가 판매자로서, 구매자가 보내온 구매 요청 (XRPL Buy Offer)
  const requestOffers = [
    { t: '새벽의 정물 No.3', a: '박서린', ed: '12 / 50', nft: '#4821', price: '1,180', buyer: '오세진', pal: ART.dawn, img: 'assets/dawn-still-life.jpg' },
  ];
  const [offerDetail, setOfferDetail] = React.useState(null);
  const [purchased, setPurchased] = React.useState(null);
  const [requestDetail, setRequestDetail] = React.useState(null);
  const [accepted, setAccepted] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  React.useEffect(() => { const t = setTimeout(() => setLoading(false), 1100); return () => clearTimeout(t); }, []);

  const handleClosePurchase = () => {
    setPurchased(null);
    setOfferDetail(null);
  };
  const handleCloseAccept = () => {
    setAccepted(null);
    setRequestDetail(null);
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', color: 'var(--es-ink)', background: 'var(--es-bg-grouped)', position: 'relative', overflow: 'hidden' }}>
      <MtNav large title="내 작품"
        right={<NavIcon n="bell" s={22} />} />
      <Scroll>
        {/* portfolio seal card */}
        <div style={{ padding: '4px 16px 0' }}>
          <div style={{ borderRadius: 'var(--es-r-xl)', padding: '20px 22px', color: '#fff',
            background: 'linear-gradient(150deg,#234534 0%,#122017 100%)', position: 'relative', overflow: 'hidden' }}>
            <div style={{ position: 'absolute', right: -34, top: -34, width: 150, height: 150, borderRadius: '50%', background: 'rgba(184,153,122,0.16)' }} />
            <div style={{ display: 'flex', alignItems: 'center', gap: 7, color: 'rgba(255,255,255,0.62)' }}>
              <Ic n="shield-check" s={15} style={{ color: 'var(--es-bronze-tint)' }} />
              <span className="es-footnote" style={{ color: 'rgba(255,255,255,0.62)' }}>인증 포트폴리오 예상 가치</span>
            </div>
            {loading
              ? <div className="es-skel es-skel--shimmer" style={{ width: 150, height: 34, marginTop: 8 }} />
              : <div className="es-large-title es-price" style={{ color: '#fff', marginTop: 6 }}>6,890 <span className="es-title-3" style={{ color: 'rgba(255,255,255,0.5)' }}>XRP</span></div>}
          </div>
        </div>

        {/* 로딩 중 — 카드+리스트 대신 중앙 스피너만 */}
        {loading && (
          <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '60px 0 40px', gap: 12 }}>
            <span className="es-spinner" />
            <span className="es-footnote es-ink-3">불러오는 중…</span>
          </div>
        )}

        {/* 받은 구매 오퍼 — 미보유 작품에 대한 판매 제안 */}
        {!loading && buyOffers.length > 0 && (
          <div style={{ padding: '20px 0 4px' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '0 16px 10px' }}>
              <span className="es-list-header" style={{ padding: 0 }}>받은 제안</span>
              <span className="es-badge es-badge--verified">{buyOffers.length}</span>
            </div>
            <div style={{ display: 'flex', gap: 10, overflowX: 'auto', padding: '0 16px 6px', WebkitOverflowScrolling: 'touch' }}>
              {buyOffers.map((x, i) => (
                <div key={i} className="es-card es-card--flat" style={{ width: 176, flexShrink: 0, cursor: 'pointer' }} onClick={() => setOfferDetail(x)}>
                  <Canvas from={x.pal[0]} to={x.pal[1]} img={x.img} h={104} style={{ borderTopLeftRadius: 'var(--es-r-lg)', borderTopRightRadius: 'var(--es-r-lg)' }}>
                    <span style={{ position: 'absolute', top: 7, left: 7 }}><SealBadge small /></span>
                  </Canvas>
                  <div style={{ padding: '10px 11px 12px' }}>
                    <div className="es-caption es-ink-3">{x.a} · 에디션 {x.ed}</div>
                    <div className="es-subhead" style={{ fontWeight: 600, marginTop: 6, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{x.t}</div>
                    <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginTop: 8 }}>
                      <div className="es-footnote es-ink-3">제안가</div>
                      <div className="es-subhead es-price" style={{ fontWeight: 700, color: 'var(--es-gold)' }}>{x.price}<span className="es-caption es-ink-3" style={{ fontWeight: 400 }}> XRP</span></div>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}

        {/* 구매 요청 — 내가 보유한 작품에 대해 구매자가 보낸 요청 */}
        {!loading && requestOffers.length > 0 && (
          <div style={{ padding: '20px 0 4px' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '0 16px 10px' }}>
              <span className="es-list-header" style={{ padding: 0 }}>보낸 제안</span>
              <span className="es-badge es-badge--verified">{requestOffers.length}</span>
            </div>
            <div style={{ display: 'flex', gap: 10, overflowX: 'auto', padding: '0 16px 6px', WebkitOverflowScrolling: 'touch' }}>
              {requestOffers.map((x, i) => (
                <div key={i} className="es-card es-card--flat" style={{ width: 176, flexShrink: 0, cursor: 'pointer' }} onClick={() => setRequestDetail(x)}>
                  <Canvas from={x.pal[0]} to={x.pal[1]} img={x.img} h={104} style={{ borderTopLeftRadius: 'var(--es-r-lg)', borderTopRightRadius: 'var(--es-r-lg)' }}>
                    <span style={{ position: 'absolute', top: 7, left: 7 }}><SealBadge small /></span>
                  </Canvas>
                  <div style={{ padding: '10px 11px 12px' }}>
                    <div className="es-caption es-ink-3">{x.a} · 에디션 {x.ed}</div>
                    <div className="es-subhead" style={{ fontWeight: 600, marginTop: 6, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{x.t}</div>
                    <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginTop: 8 }}>
                      <div className="es-footnote es-ink-3">요청가</div>
                      <div className="es-subhead es-price" style={{ fontWeight: 700, color: 'var(--es-gold)' }}>{x.price}<span className="es-caption es-ink-3" style={{ fontWeight: 400 }}> XRP</span></div>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}

        {/* filter segment */}
        {!loading && (
        <div style={{ padding: '18px 16px 12px' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '0 0 10px' }}>
            <span className="es-list-header" style={{ padding: 0 }}>보유 작품</span>
          </div>
          <div className="es-segment">
            {[['전체', assets.length], ['보관중', assets.filter(x => x.trade === '보관중').length], ['거래중', assets.filter(x => x.trade === '거래중').length]].map(([t, c]) => (
              <button key={t} className="es-segment__item" aria-selected={t === filter} onClick={() => setFilter(t)}>{t} ({c})</button>
            ))}
          </div>
        </div>)}

        {/* asset list */}
        {!loading && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12, padding: '0 16px 20px' }}>
          {shown.map((x, i) => (
            <div key={i} className="es-card es-card--flat" style={{ display: 'flex', cursor: 'pointer' }}>
              <Canvas from={x.pal[0]} to={x.pal[1]} img={x.img} h={104} style={{ width: 104, flexShrink: 0 }}>
                <span style={{ position: 'absolute', top: 7, left: 7 }}><SealBadge small /></span>
              </Canvas>
              <div style={{ flex: 1, minWidth: 0, padding: '11px 12px 11px 13px', display: 'flex', flexDirection: 'column' }}>
                <div className="es-caption es-ink-3">{x.a} · 에디션 {x.ed}</div>
                <div className="es-subhead" style={{ fontWeight: 600, marginTop: 1, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{x.t}</div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 'auto' }}>
                  <TradeTag status={x.trade} />
                  <span className="es-caption es-ink-3 es-mono">NFT {x.nft}</span>
                </div>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'space-between', alignItems: 'flex-end', padding: '11px 12px' }}>
                <span className="es-row__chev"><Ic n="chevron-right" s={18} /></span>
                {x.price && <div className="es-subhead es-price" style={{ fontWeight: 700 }}>{x.price}<span className="es-caption es-ink-3" style={{ fontWeight: 400 }}> XRP</span></div>}
              </div>
            </div>
          ))}
          <p className="es-footnote es-ink-3" style={{ textAlign: 'center', marginTop: 4 }}>
            소유·거래 이력은 XRPL 원장에 영구 기록됩니다
          </p>
        </div>)}
      </Scroll>
      <MainTabBar active={active} onChange={onTab} />

      {/* 구매 오퍼 상세 — push-style overlay */}
      <div style={{ position: 'absolute', inset: 0, zIndex: 60, pointerEvents: offerDetail ? 'auto' : 'none' }}>
        <div style={{ position: 'absolute', inset: 0, background: 'var(--es-bg-grouped)', color: 'var(--es-ink)',
          display: 'flex', flexDirection: 'column',
          transform: offerDetail ? 'translateX(0)' : 'translateX(100%)',
          transition: 'transform 0.36s cubic-bezier(0.32,0.72,0,1)' }}>
          {offerDetail && (
            <BuyOfferDetail offer={offerDetail} onClose={() => setOfferDetail(null)}
              onBuy={() => setPurchased(offerDetail)} />
          )}
        </div>
      </div>

      {/* 구매 완료 결과 — 오퍼 상세 위로 fade/scale in */}
      <div style={{ position: 'absolute', inset: 0, zIndex: 70, pointerEvents: purchased ? 'auto' : 'none' }}>
        <div style={{ position: 'absolute', inset: 0, background: 'var(--es-bg-grouped)', color: 'var(--es-ink)',
          display: 'flex', flexDirection: 'column',
          opacity: purchased ? 1 : 0,
          transform: purchased ? 'scale(1)' : 'scale(0.97)',
          transition: 'opacity 0.32s ease, transform 0.32s cubic-bezier(0.32,0.72,0,1)' }}>
          {purchased && (
            <PurchaseSuccess offer={purchased} onDone={handleClosePurchase} />
          )}
        </div>
      </div>

      {/* 구매 요청 상세 — push-style overlay */}
      <div style={{ position: 'absolute', inset: 0, zIndex: 60, pointerEvents: requestDetail ? 'auto' : 'none' }}>
        <div style={{ position: 'absolute', inset: 0, background: 'var(--es-bg-grouped)', color: 'var(--es-ink)',
          display: 'flex', flexDirection: 'column',
          transform: requestDetail ? 'translateX(0)' : 'translateX(100%)',
          transition: 'transform 0.36s cubic-bezier(0.32,0.72,0,1)' }}>
          {requestDetail && (
            <PurchaseRequestDetail offer={requestDetail} onClose={() => setRequestDetail(null)}
              onAccept={() => setAccepted(requestDetail)} />
          )}
        </div>
      </div>

      {/* 판매 완료 결과 — 요청 상세 위로 fade/scale in */}
      <div style={{ position: 'absolute', inset: 0, zIndex: 70, pointerEvents: accepted ? 'auto' : 'none' }}>
        <div style={{ position: 'absolute', inset: 0, background: 'var(--es-bg-grouped)', color: 'var(--es-ink)',
          display: 'flex', flexDirection: 'column',
          opacity: accepted ? 1 : 0,
          transform: accepted ? 'scale(1)' : 'scale(0.97)',
          transition: 'opacity 0.32s ease, transform 0.32s cubic-bezier(0.32,0.72,0,1)' }}>
          {accepted && (
            <AcceptSuccess offer={accepted} onDone={handleCloseAccept} />
          )}
        </div>
      </div>
    </div>
  );
}

function BuyOfferDetail({ offer, onClose, onBuy }) {
  const price = parseFloat(String(offer.price).replace(/,/g, '')) || 0;
  const fmt = (n) => n.toLocaleString();

  return (
    <>
      <MtNav title={offer.t} left={<NavIcon n="chevron-left" s={22} onClick={onClose} />} />
      <Scroll>
        <Canvas from={offer.pal[0]} to={offer.pal[1]} img={offer.img} h={220}>
          <span style={{ position: 'absolute', bottom: 14, left: 16 }}>
            <span className="es-badge es-badge--verified"><Ic n="shield-check" s={12} />정품 인증</span>
          </span>
        </Canvas>
        <div style={{ padding: '18px 16px 8px' }}>
          <div className="es-caption es-ink-3">{offer.a} · 에디션 {offer.ed}</div>
          <div className="es-title-2" style={{ fontWeight: 700, marginTop: 3 }}>{offer.t}</div>
          <div style={{ marginTop: 10 }}>
            <span className="es-caption es-ink-3 es-mono">NFT {offer.nft}</span>
          </div>
        </div>

        <div style={{ padding: '16px 16px 8px' }}>
          <div className="es-list-header">제안 내용</div>
          <div className="es-card" style={{ marginTop: 8, padding: '4px 16px', boxShadow: 'var(--es-shadow-1)' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', padding: '13px 0', borderBottom: '0.5px solid var(--es-separator)' }}>
              <span className="es-subhead es-ink-2">판매자</span>
              <span className="es-subhead" style={{ fontWeight: 600 }}>{offer.seller}</span>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between', padding: '13px 0' }}>
              <span className="es-subhead" style={{ fontWeight: 700 }}>총 결제 금액</span>
              <span className="es-subhead es-mono es-price" style={{ fontWeight: 700 }}>{fmt(price)} XRP</span>
            </div>
          </div>
          <div className="es-card es-card--flat" style={{ display: 'flex', gap: 10, padding: '13px 14px', alignItems: 'flex-start', marginTop: 10 }}>
            <span style={{ color: 'var(--es-ink-3)', flexShrink: 0, marginTop: 1 }}><Ic n="info" s={17} /></span>
            <div className="es-footnote es-ink-3" style={{ lineHeight: 1.5 }}>
              제안을 수락하면 XRPL 블록체인에 소유권 이전이 즉시 기록되며, 거래가 완료됩니다.
              <br /><br />
              제안가에는 에버씰 플랫폼 수수료(1%)와 작가 로열티(5%) 등이 포함되어 있습니다.
            </div>
          </div>
        </div>
      </Scroll>

      <div style={{ flexShrink: 0, padding: '12px 16px 30px', background: 'rgba(241,242,238,0.92)',
        backdropFilter: 'blur(20px)', WebkitBackdropFilter: 'blur(20px)',
        borderTop: '0.5px solid var(--es-separator)', display: 'flex', flexDirection: 'column', gap: 8 }}>
        <button className="es-btn es-btn--gold es-btn--block" onClick={onBuy}><Ic n="check" s={18} sw={2.2} />구매하기</button>
        <button className="es-btn es-btn--ghost es-btn--block" style={{ color: 'var(--es-danger)' }} onClick={onClose}>거절하기</button>
      </div>
    </>
  );
}

// ── 구매 완료 결과 화면 ──
function PurchaseSuccess({ offer, onDone }) {
  const price = parseFloat(String(offer.price).replace(/,/g, '')) || 0;
  const fmt = (n) => n.toLocaleString();
  const now = new Date();
  const stamp = `${now.getFullYear()}.${String(now.getMonth() + 1).padStart(2, '0')}.${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;

  return (
    <>
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column' }}>
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center',
          justifyContent: 'center', padding: '60px 28px 0', textAlign: 'center' }}>
          <div style={{ width: 84, height: 84, borderRadius: '50%', display: 'grid', placeItems: 'center',
            background: 'var(--es-green-tint, rgba(74,124,89,0.14))', border: '1.5px solid var(--es-green-border)',
            color: 'var(--es-green)', marginBottom: 22 }}>
            <Ic n="check" s={40} sw={2.4} />
          </div>
          <div className="es-title-1" style={{ fontWeight: 700 }}>구매가 완료되었어요</div>
          <p className="es-callout es-ink-3" style={{ marginTop: 8, maxWidth: '26ch', lineHeight: 1.55 }}>
            소유권 이전이 XRPL 원장에 기록되었어요.
          </p>

          <div className="es-card" style={{ width: '100%', marginTop: 30, padding: '4px 16px', boxShadow: 'var(--es-shadow-1)', textAlign: 'left' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '14px 0', borderBottom: '0.5px solid var(--es-separator)' }}>
              <Canvas from={offer.pal[0]} to={offer.pal[1]} img={offer.img} h={44} style={{ width: 44, borderRadius: 9, flexShrink: 0 }} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div className="es-subhead" style={{ fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{offer.t}</div>
                <div className="es-caption es-ink-3" style={{ marginTop: 2 }}>{offer.a} · 에디션 {offer.ed}</div>
              </div>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12, padding: '13px 0', borderBottom: '0.5px solid var(--es-separator)' }}>
              <span className="es-subhead es-ink-2" style={{ flexShrink: 0 }}>NFT ID</span>
              <span className="es-subhead es-mono" style={{ minWidth: 0, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{offer.nft}</span>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between', padding: '13px 0', borderBottom: '0.5px solid var(--es-separator)' }}>
              <span className="es-subhead es-ink-2">결제 시각</span>
              <span className="es-subhead es-mono">{stamp}</span>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between', padding: '13px 0' }}>
              <span className="es-subhead" style={{ fontWeight: 700 }}>총 결제 금액</span>
              <span className="es-subhead es-mono es-price" style={{ fontWeight: 700, color: 'var(--es-gold)' }}>{fmt(price)} XRP</span>
            </div>
          </div>
        </div>
      </div>

      <div style={{ flexShrink: 0, padding: '12px 16px 30px' }}>
        <button className="es-btn es-btn--gold es-btn--block" onClick={onDone}>확인</button>
      </div>
    </>
  );
}

// ── 구매 요청 상세 (판매자 시점 — 구매자가 보낸 요청을 수락/거절) ──
function PurchaseRequestDetail({ offer, onClose, onAccept }) {
  const price = parseFloat(String(offer.price).replace(/,/g, '')) || 0;
  const fmt = (n) => n.toLocaleString();

  return (
    <>
      <MtNav title={offer.t} left={<NavIcon n="chevron-left" s={22} onClick={onClose} />} />
      <Scroll>
        <Canvas from={offer.pal[0]} to={offer.pal[1]} img={offer.img} h={220}>
          <span style={{ position: 'absolute', bottom: 14, left: 16 }}>
            <span className="es-badge es-badge--verified"><Ic n="shield-check" s={12} />정품 인증</span>
          </span>
        </Canvas>
        <div style={{ padding: '18px 16px 8px' }}>
          <div className="es-caption es-ink-3">{offer.a} · 에디션 {offer.ed}</div>
          <div className="es-title-2" style={{ fontWeight: 700, marginTop: 3 }}>{offer.t}</div>
          <div style={{ marginTop: 10 }}>
            <span className="es-caption es-ink-3 es-mono">NFT {offer.nft}</span>
          </div>
        </div>

        <div style={{ padding: '16px 16px 8px' }}>
          <div className="es-list-header">요청 내용</div>
          <div className="es-card" style={{ marginTop: 8, padding: '4px 16px', boxShadow: 'var(--es-shadow-1)' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', padding: '13px 0', borderBottom: '0.5px solid var(--es-separator)' }}>
              <span className="es-subhead es-ink-2">구매자</span>
              <span className="es-subhead" style={{ fontWeight: 600 }}>{offer.buyer}</span>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between', padding: '13px 0' }}>
              <span className="es-subhead" style={{ fontWeight: 700 }}>총 수령 금액</span>
              <span className="es-subhead es-mono es-price" style={{ fontWeight: 700 }}>{fmt(price)} XRP</span>
            </div>
          </div>
          <div className="es-card es-card--flat" style={{ display: 'flex', gap: 10, padding: '13px 14px', alignItems: 'flex-start', marginTop: 10 }}>
            <span style={{ color: 'var(--es-ink-3)', flexShrink: 0, marginTop: 1 }}><Ic n="info" s={17} /></span>
            <div className="es-footnote es-ink-3" style={{ lineHeight: 1.5 }}>
              요청을 수락하면 XRPL 블록체인에 소유권 이전이 즉시 기록되며, 거래가 완료됩니다.
              <br /><br />
              수령액에는 에버씰 플랫폼 수수료(1%)가 차감되어 반영되어 있습니다.
            </div>
          </div>
        </div>
      </Scroll>

      <div style={{ flexShrink: 0, padding: '12px 16px 30px', background: 'rgba(241,242,238,0.92)',
        backdropFilter: 'blur(20px)', WebkitBackdropFilter: 'blur(20px)',
        borderTop: '0.5px solid var(--es-separator)', display: 'flex', flexDirection: 'column', gap: 8 }}>
        <button className="es-btn es-btn--gold es-btn--block" onClick={onAccept}><Ic n="check" s={18} sw={2.2} />수락하기</button>
        <button className="es-btn es-btn--ghost es-btn--block" style={{ color: 'var(--es-danger)' }} onClick={onClose}>거절하기</button>
      </div>
    </>
  );
}

// ── 판매 완료 결과 화면 (판매자 시점) ──
function AcceptSuccess({ offer, onDone }) {
  const price = parseFloat(String(offer.price).replace(/,/g, '')) || 0;
  const fmt = (n) => n.toLocaleString();
  const now = new Date();
  const stamp = `${now.getFullYear()}.${String(now.getMonth() + 1).padStart(2, '0')}.${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;

  return (
    <>
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column' }}>
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center',
          justifyContent: 'center', padding: '60px 28px 0', textAlign: 'center' }}>
          <div style={{ width: 84, height: 84, borderRadius: '50%', display: 'grid', placeItems: 'center',
            background: 'var(--es-green-tint, rgba(74,124,89,0.14))', border: '1.5px solid var(--es-green-border)',
            color: 'var(--es-green)', marginBottom: 22 }}>
            <Ic n="check" s={40} sw={2.4} />
          </div>
          <div className="es-title-1" style={{ fontWeight: 700 }}>판매가 완료되었어요</div>
          <p className="es-callout es-ink-3" style={{ marginTop: 8, maxWidth: '26ch', lineHeight: 1.55 }}>
            소유권 이전이 XRPL 원장에 기록되었어요.
          </p>

          <div className="es-card" style={{ width: '100%', marginTop: 30, padding: '4px 16px', boxShadow: 'var(--es-shadow-1)', textAlign: 'left' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '14px 0', borderBottom: '0.5px solid var(--es-separator)' }}>
              <Canvas from={offer.pal[0]} to={offer.pal[1]} img={offer.img} h={44} style={{ width: 44, borderRadius: 9, flexShrink: 0 }} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div className="es-subhead" style={{ fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{offer.t}</div>
                <div className="es-caption es-ink-3" style={{ marginTop: 2 }}>{offer.a} · 에디션 {offer.ed}</div>
              </div>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12, padding: '13px 0', borderBottom: '0.5px solid var(--es-separator)' }}>
              <span className="es-subhead es-ink-2" style={{ flexShrink: 0 }}>NFT ID</span>
              <span className="es-subhead es-mono" style={{ minWidth: 0, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{offer.nft}</span>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between', padding: '13px 0', borderBottom: '0.5px solid var(--es-separator)' }}>
              <span className="es-subhead es-ink-2">완료 시각</span>
              <span className="es-subhead es-mono">{stamp}</span>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between', padding: '13px 0' }}>
              <span className="es-subhead" style={{ fontWeight: 700 }}>총 수령 금액</span>
              <span className="es-subhead es-mono es-price" style={{ fontWeight: 700, color: 'var(--es-gold)' }}>{fmt(price)} XRP</span>
            </div>
          </div>
        </div>
      </div>

      <div style={{ flexShrink: 0, padding: '12px 16px 30px' }}>
        <button className="es-btn es-btn--gold es-btn--block" onClick={onDone}>확인</button>
      </div>
    </>
  );
}

// ═════════════════════════════════════════════════════════
//  TAB 2 — REGISTRATION  (NFC → NFT 등록 · EVS-iOS 005)
// ═════════════════════════════════════════════════════════

// recently-checked artworks (shown in the pull-down sheet)
const RECENT_CHECKED = [
  { t: '새벽의 정물 No.3', a: '박서린', ed: '12 / 50', nft: '#4821', time: '오늘 14:20', pal: ART.dawn, img: 'assets/dawn-still-life.jpg' },
  { t: '겹의 시간', a: '한도윤', ed: '04 / 20', nft: '#5102', time: '오늘 11:05', pal: ART.layers },
  { t: '백자 달항아리', a: '오세진', ed: '01 / 01', nft: '#3380', time: '어제 18:42', pal: ART.moon },
  { t: '심해의 빛', a: '이정안', ed: '07 / 30', nft: '#2910', time: '6월 5일', pal: ART.abyss },
  { t: '청록 변주', a: '김서진', ed: '09 / 25', nft: '#1740', time: '6월 3일', pal: ART.blue, img: 'assets/teal-variations.jpg' },
];

// ── iOS-style pull-down sheet (drag the grabber down to dismiss) ──
function RecentCheckedSheet({ open, onClose }) {
  const [dragY, setDragY] = React.useState(0);
  const [dragging, setDragging] = React.useState(false);
  const startY = React.useRef(0);

  React.useEffect(() => { if (open) setDragY(0); }, [open]);

  const onDown = (e) => {
    setDragging(true);
    startY.current = e.clientY;
    if (e.currentTarget.setPointerCapture) e.currentTarget.setPointerCapture(e.pointerId);
  };
  const onMove = (e) => {
    if (!dragging) return;
    setDragY(Math.max(0, e.clientY - startY.current));
  };
  const onUp = () => {
    if (!dragging) return;
    setDragging(false);
    if (dragY > 130) onClose();
    setDragY(0);
  };

  const ease = 'transform 0.46s cubic-bezier(0.32,0.72,0,1)';

  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: 200,
      pointerEvents: open ? 'auto' : 'none' }}>
      {/* dimmed backdrop */}
      <div onClick={onClose} style={{ position: 'absolute', inset: 0,
        background: 'rgba(0,0,0,0.32)', opacity: open ? 1 : 0,
        transition: 'opacity 0.4s ease' }} />

      {/* sheet panel */}
      <div style={{ position: 'absolute', left: 0, right: 0, top: 50, bottom: 0,
        background: 'var(--es-bg-grouped)', color: 'var(--es-ink)', borderTopLeftRadius: 14, borderTopRightRadius: 14,
        boxShadow: '0 -10px 40px rgba(0,0,0,0.28)', overflow: 'hidden',
        display: 'flex', flexDirection: 'column',
        transform: open ? `translateY(${dragY}px)` : 'translateY(100%)',
        transition: dragging ? 'none' : ease }}>

        {/* draggable header */}
        <div onPointerDown={onDown} onPointerMove={onMove} onPointerUp={onUp} onPointerCancel={onUp}
          style={{ flexShrink: 0, paddingTop: 8, cursor: 'grab', touchAction: 'none',
            background: 'rgba(241,242,238,0.92)', backdropFilter: 'blur(20px)', WebkitBackdropFilter: 'blur(20px)' }}>
          {/* grabber */}
          <div style={{ display: 'flex', justifyContent: 'center', padding: '2px 0 20px' }}>
            <div style={{ width: 38, height: 5, borderRadius: 100, background: 'var(--es-ink-4)' }} />
          </div>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between',
            padding: '6px 18px 18px', borderBottom: '0.5px solid var(--es-separator)' }}>
            <div className="es-title-3" style={{ color: 'var(--es-ink)' }}>최근 확인한 작품</div>
            <button className="es-navbar__btn" onClick={onClose} style={{ color: 'var(--es-ink-3)' }}>
              <Ic n="xmark" s={18} sw={2.2} />
            </button>
          </div>
        </div>

        {/* list */}
        <div style={{ flex: 1, overflow: 'auto', WebkitOverflowScrolling: 'touch', padding: '16px 16px 28px' }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
            {RECENT_CHECKED.map((x, i) => (
              <div key={i} className="es-card es-card--flat" style={{ display: 'flex', cursor: 'pointer', alignItems: 'center', gap: 14, padding: '14px 14px' }}>
                <Canvas from={x.pal[0]} to={x.pal[1]} img={x.img} h={60} style={{ width: 60, borderRadius: 13, flexShrink: 0 }}>
                  <span style={{ position: 'absolute', top: 5, left: 5 }}><SealBadge small /></span>
                </Canvas>
                <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', justifyContent: 'center', gap: 5 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 0 }}>
                    <span className="es-subhead" style={{ fontWeight: 600, color: 'var(--es-ink)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{x.t}</span>
                    <span style={{ display: 'inline-flex', flexShrink: 0, width: 17, height: 17, borderRadius: '50%',
                      background: 'var(--es-green)', color: '#fff', alignItems: 'center', justifyContent: 'center' }}>
                      <Ic n="check" s={11} sw={2.8} />
                    </span>
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 9 }}>
                    <span className="es-caption es-ink-3" style={{ whiteSpace: 'nowrap' }}>{x.a}</span>
                    <span style={{ width: 1, height: 11, background: 'var(--es-separator-strong)', flexShrink: 0 }} />
                    <span className="es-caption es-ink-3" style={{ whiteSpace: 'nowrap' }}>{x.time}</span>
                  </div>
                </div>
                <span className="es-row__chev" style={{ flexShrink: 0 }}><Ic n="chevron-right" s={18} /></span>
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

function RegisterScreen({ active = 'register', onTab }) {
  const steps = [
    ['nfc', '태그 스캔', '작품의 NFC를 인식해요'],
    ['brush', '작품 정보 입력', '사진과 이름을 차근차근 입력해요'],
    ['seal', '등록 완료', '정품 인증서가 발급돼요'],
  ];
  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', color: 'var(--es-ink)', background: 'var(--es-bg-grouped)' }}>
      <MtNav large title="작품 등록" />
      <Scroll>
        {/* guide */}
        <div style={{ padding: '32px 16px 12px' }}>
          <div className="es-list-header">이렇게 진행돼요</div>
          <div style={{ position: 'relative', paddingLeft: 6, marginTop: 10 }}>
            {steps.map(([ic, t, d], i) => (
              <div key={i} style={{ display: 'flex', gap: 16, paddingBottom: i < steps.length - 1 ? 34 : 0, position: 'relative' }}>
                {/* connector */}
                {i < steps.length - 1 && (
                  <div style={{ position: 'absolute', left: 18, top: 42, bottom: 2, width: 2, background: 'var(--es-separator-strong)' }} />
                )}
                <div style={{ width: 38, height: 38, borderRadius: '50%', flexShrink: 0, zIndex: 1,
                  background: 'var(--es-surface)', border: '1.5px solid var(--es-green-border)',
                  display: 'grid', placeItems: 'center', color: 'var(--es-green)' }}>
                  <Ic n={ic} s={19} />
                </div>
                <div style={{ flex: 1, paddingTop: 4 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 7 }}>
                    <span className="es-caption-2" style={{ color: 'var(--es-bronze)', fontWeight: 700 }}>STEP {i + 1}</span>
                    <span className="es-subhead" style={{ fontWeight: 600 }}>{t}</span>
                  </div>
                  <div className="es-footnote es-ink-3" style={{ marginTop: 3, lineHeight: 1.45 }}>{d}</div>
                </div>
              </div>
            ))}
          </div>
        </div>

        {/* reassurance note */}
        <div style={{ padding: '20px 16px 8px' }}>
          <div className="es-card es-card--flat" style={{ display: 'flex', gap: 12, padding: '16px 15px', alignItems: 'flex-start' }}>
            <span style={{ color: 'var(--es-bronze)', flexShrink: 0, marginTop: 1 }}><Ic n="shield-check" s={20} /></span>
            <div className="es-footnote es-ink-2" style={{ lineHeight: 1.5 }}>
              등록된 작품은 XRPL 원장에 NFT로 발행되어 소유권과 정품 여부가 영구히 보증됩니다.
            </div>
          </div>
        </div>
      </Scroll>

      {/* sticky CTA */}
      <div style={{ flexShrink: 0, padding: '12px 16px 12px', background: 'rgba(241,242,238,0.92)',
        backdropFilter: 'blur(20px)', WebkitBackdropFilter: 'blur(20px)',
        borderTop: '0.5px solid var(--es-separator)' }}>
        <button className="es-btn es-btn--gold es-btn--block"><Ic n="plus" s={19} sw={2.2} />작품 등록 시작하기</button>
      </div>
      <MainTabBar active={active} onChange={onTab} />
    </div>
  );
}

// ═════════════════════════════════════════════════════════
//  TAB 3 — VERIFICATION  (정품 확인 · EVS-iOS 010)
// ═════════════════════════════════════════════════════════
function VerifyScreen({ active = 'verify', onTab }) {
  const [sheet, setSheet] = React.useState(false);
  return (
    <div style={{ position: 'relative', height: '100%', background: '#000' }}>
      {/* main screen — scales back like an iOS card when the sheet is up */}
      <div style={{ display: 'flex', flexDirection: 'column', height: '100%', color: '#fff',
      background: 'linear-gradient(180deg,#1a3327 0%,#0f1b14 100%)', overflow: 'hidden',
      transformOrigin: 'center top',
      transform: sheet ? 'scale(0.93) translateY(10px)' : 'none',
      borderRadius: sheet ? 14 : 0,
      transition: 'transform 0.46s cubic-bezier(0.32,0.72,0,1), border-radius 0.46s ease' }}>
      <MtNav title="정품 확인" dark
        right={<NavIcon n="clock" s={22} dark onClick={() => setSheet(true)} />} />

      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center',
        justifyContent: 'center', padding: '0 28px', textAlign: 'center' }}>
        <div style={{ position: 'relative', width: 208, height: 208, display: 'grid', placeItems: 'center', marginBottom: 36 }}>
          {[0, 1, 2].map(i => (
            <span key={i} style={{ position: 'absolute', inset: 0, borderRadius: '50%',
              border: '1.5px solid rgba(184,153,122,0.4)', animation: `mtPulse 2.6s ${i * 0.85}s ease-out infinite` }} />
          ))}
          <div style={{ width: 124, height: 124, borderRadius: '50%',
            background: 'radial-gradient(circle at 50% 35%, #2c4a3a, #142a20)',
            border: '1px solid rgba(184,153,122,0.38)', display: 'grid', placeItems: 'center',
            color: 'var(--es-bronze-tint)', boxShadow: '0 0 70px rgba(184,153,122,0.2)' }}>
            <Ic n="nfc" s={56} sw={1.5} />
          </div>
        </div>
        <div className="es-title-2" style={{ color: '#fff' }}>작품에 휴대폰을 가까이 대세요</div>
        <p className="es-callout" style={{ color: 'rgba(255,255,255,0.62)', marginTop: 10, maxWidth: '26ch', lineHeight: 1.55 }}>
          태그를 대면 진짜 작품인지 바로 확인해 드려요.
        </p>
      </div>

      {/* CTA */}
      <div style={{ flexShrink: 0, padding: '16px 24px 14px' }}>
        <button className="es-btn es-btn--gold es-btn--block"><Ic n="wave" s={19} />스캔 시작</button>
      </div>
      <MainTabBar active={active} onChange={onTab} />
      </div>

      <RecentCheckedSheet open={sheet} onClose={() => setSheet(false)} />
    </div>
  );
}

// ═════════════════════════════════════════════════════════
//  TAB 4 — MY PAGE  (마이페이지 · EVS-iOS 007 / 013)
// ═════════════════════════════════════════════════════════
function MyPageScreen({ active = 'my', onTab, initialReceive = false, initialSend = false }) {
  const [showTx, setShowTx] = React.useState(false);
  const [showSettle, setShowSettle] = React.useState(false);
  const [showReceive, setShowReceive] = React.useState(initialReceive);
  const [showSend, setShowSend] = React.useState(initialSend);
  const walletAddr = 'rEv9aLkT2mWqF8xN3bYcZpR6vHsDnq8kP2';
  const destinationTag = '000482017';
  return (
    <div style={{ position: 'relative', display: 'flex', flexDirection: 'column', height: '100%', color: 'var(--es-ink)', background: 'var(--es-bg-grouped)', overflow: 'hidden' }}>
      <MtNav large title="내 정보" />
      <Scroll>
        {/* profile header */}
        <div style={{ padding: '2px 16px 0' }}>
          <div className="es-card" style={{ padding: '18px 16px', display: 'flex', alignItems: 'center', gap: 14, boxShadow: 'var(--es-shadow-1)' }}>
            <div className="es-avatar" style={{ width: 60, height: 60, background: 'var(--es-green-deep)', color: 'var(--es-bronze-tint)', flexShrink: 0 }}>
              <Ic n="brush" s={28} />
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div className="es-title-3" style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                박서린 <Ic n="shield-check" s={17} style={{ color: 'var(--es-bronze)' }} />
              </div>
              <div className="es-caption es-ink-3" style={{ marginTop: 2 }}>인증 작가 · 서울</div>
              <WalletAddr addr="rEv9aLkT2mWqF8xN3bYcZpR6vHsDnq8kP2" />
            </div>
            <Ic n="chevron-right" s={18} style={{ color: 'var(--es-ink-4)' }} />
          </div>
        </div>

        {/* wallet card */}
        <div style={{ padding: '14px 16px 0' }}>
          <div style={{ borderRadius: 'var(--es-r-xl)', padding: '18px 20px', color: '#fff',
            background: 'linear-gradient(150deg,#16281e 0%,#122017 100%)', position: 'relative', overflow: 'hidden' }}>
            <div style={{ position: 'absolute', right: -30, top: -30, width: 130, height: 130, borderRadius: '50%', background: 'rgba(184,153,122,0.14)' }} />
            <div className="es-footnote" style={{ color: 'rgba(255,255,255,0.55)' }}>지갑 잔액</div>
            <div className="es-title-1 es-price" style={{ color: '#fff', marginTop: 4 }}>4,820.5 <span className="es-title-3" style={{ color: 'rgba(255,255,255,0.5)' }}>XRP</span></div>
            <div className="es-caption" style={{ color: 'rgba(255,255,255,0.45)', marginTop: 2 }}>≈ ₩8,914,000</div>
            <div style={{ display: 'flex', gap: 10, marginTop: 16 }}>
              <button className="es-btn es-btn--sm" style={{ flex: 1, background: 'rgba(255,255,255,0.14)', color: '#fff' }} onClick={() => setShowReceive(true)}><Ic n="arrow-down-left" s={17} />QR로 받기</button>
              <button className="es-btn es-btn--sm" style={{ flex: 1, background: 'var(--es-bronze)', color: '#fff' }} onClick={() => setShowSend(true)}><Ic n="arrow-up-right" s={17} />보내기</button>
            </div>
          </div>
        </div>

        {/* records group (EVS-iOS 013 거래/정산 내역) */}
        <div style={{ padding: '20px 16px 0' }}>
          <div className="es-list-header">내역</div>
          <div className="es-list">
            {[
              ['arrow-up-right', 'var(--es-green)', '거래 내역', '12건', () => setShowTx(true)],
              ['creditcard', 'var(--es-bronze)', '정산 내역', '4건', () => setShowSettle(true)],
              ['globe', 'var(--es-sage)', '라이선싱 내역', '4건', null],
              ['shield-check', 'var(--es-bronze)', '정품 인증 내역', '23건', null],
            ].map(([ic, bg, title, detail, onClick], i) => (
              <div key={i} className="es-row es-row--tappable" onClick={onClick || undefined}>
                <div className="es-row__icon" style={{ background: bg }}><Ic n={ic} s={17} /></div>
                <div className="es-row__text"><div className="es-row__title" style={{ fontSize: 16 }}>{title}</div></div>
                {detail && <span className="es-row__detail" style={{ fontSize: 15 }}>{detail}</span>}
                <span className="es-row__chev"><Ic n="chevron-right" s={18} /></span>
              </div>
            ))}
          </div>
        </div>

        {/* account group */}
        <div style={{ padding: '20px 16px 0' }}>
          <div className="es-list-header">계정</div>
          <div className="es-list">
            {[
              ['wallet', 'var(--es-bronze)', '지갑', null],
              ['person', 'var(--es-ink-2)', '계정 정보', null],
              ['bell', 'var(--es-warning)', '알림 설정', null],
              ['lock', 'var(--es-ink-2)', '보안 · 지갑 백업', null],
            ].map(([ic, bg, title, detail], i) => (
              <div key={i} className="es-row es-row--tappable">
                <div className="es-row__icon" style={{ background: bg }}><Ic n={ic} s={17} /></div>
                <div className="es-row__text"><div className="es-row__title" style={{ fontSize: 16 }}>{title}</div></div>
                {detail && <span className="es-row__detail" style={{ fontSize: 15 }}>{detail}</span>}
                <span className="es-row__chev"><Ic n="chevron-right" s={18} /></span>
              </div>
            ))}
          </div>
        </div>

        {/* logout */}
        <div style={{ padding: '18px 16px 28px' }}>
          <button className="es-btn es-btn--destructive es-btn--block" style={{ gap: 8 }}>
            <Ic n="logout" s={18} />로그아웃
          </button>
          <p className="es-footnote es-ink-3" style={{ textAlign: 'center', marginTop: 14 }}>EverSeal · v1.0.0</p>
        </div>
      </Scroll>
      <MainTabBar active={active} onChange={onTab} />

      {/* 거래 내역 — push-style overlay */}
      <div style={{ position: 'absolute', inset: 0, zIndex: 60, pointerEvents: showTx ? 'auto' : 'none' }}>
        <div style={{ position: 'absolute', inset: 0, background: 'var(--es-bg-grouped)', color: 'var(--es-ink)',
          display: 'flex', flexDirection: 'column',
          transform: showTx ? 'translateX(0)' : 'translateX(100%)',
          transition: 'transform 0.36s cubic-bezier(0.32,0.72,0,1)' }}>
          {showTx && <TransactionHistoryScreen onClose={() => setShowTx(false)} />}
        </div>
      </div>

      {/* 정산 내역 — push-style overlay */}
      <div style={{ position: 'absolute', inset: 0, zIndex: 60, pointerEvents: showSettle ? 'auto' : 'none' }}>
        <div style={{ position: 'absolute', inset: 0, background: 'var(--es-bg-grouped)', color: 'var(--es-ink)',
          display: 'flex', flexDirection: 'column',
          transform: showSettle ? 'translateX(0)' : 'translateX(100%)',
          transition: 'transform 0.36s cubic-bezier(0.32,0.72,0,1)' }}>
          {showSettle && <SettlementHistoryScreen onClose={() => setShowSettle(false)} />}
        </div>
      </div>

      {/* 받기 — modal bottom sheet */}
      <div onClick={() => showReceive && setShowReceive(false)} style={{
        position: 'absolute', inset: 0, zIndex: 60, background: 'rgba(18,32,23,0.42)',
        opacity: showReceive ? 1 : 0, pointerEvents: showReceive ? 'auto' : 'none', transition: 'opacity .28s ease',
      }} />
      <div style={{
        position: 'absolute', left: 0, right: 0, bottom: 0, zIndex: 61, maxHeight: '86%',
        background: 'var(--es-bg-grouped)', color: 'var(--es-ink)', borderTopLeftRadius: 22, borderTopRightRadius: 22,
        boxShadow: '0 -12px 44px rgba(0,0,0,0.20)', display: 'flex', flexDirection: 'column',
        transform: showReceive ? 'translateY(0)' : 'translateY(102%)',
        transition: 'transform .38s cubic-bezier(.32,.72,0,1)', pointerEvents: showReceive ? 'auto' : 'none',
      }}>
        {showReceive && <ReceiveScreen addr={walletAddr} tag={destinationTag} onClose={() => setShowReceive(false)} />}
      </div>

      {/* 보내기 — push-style overlay */}
      <div style={{ position: 'absolute', inset: 0, zIndex: 60, pointerEvents: showSend ? 'auto' : 'none' }}>
        <div style={{ position: 'absolute', inset: 0, background: 'var(--es-bg-grouped)', color: 'var(--es-ink)',
          display: 'flex', flexDirection: 'column',
          transform: showSend ? 'translateX(0)' : 'translateX(100%)',
          transition: 'transform 0.36s cubic-bezier(0.32,0.72,0,1)' }}>
          {showSend && <SendScreen balance="4,820.5" onClose={() => setShowSend(false)} />}
        </div>
      </div>
    </div>
  );
}

// ── 받기 (XRP 수신) ──
function ReceiveScreen({ addr, tag, onClose }) {
  const [copied, setCopied] = React.useState(''); // '' | 'addr' | 'tag'
  const copy = (which, val) => {
    try { navigator.clipboard && navigator.clipboard.writeText(val); } catch (e) {}
    setCopied(which); setTimeout(() => setCopied(''), 1600);
  };
  const Row = ({ label, value, id }) => (
    <div style={{ marginTop: 12 }}>
      <div className="es-caption es-ink-3" style={{ marginBottom: 6 }}>{label}</div>
      <div style={{ background: 'var(--es-surface-2)', border: '0.5px solid var(--es-separator)',
        borderRadius: 'var(--es-r-md)', padding: '12px 14px', display: 'flex', alignItems: 'center', gap: 10 }}>
        <span className="es-mono es-footnote" style={{ flex: 1, wordBreak: 'break-all', lineHeight: 1.45 }}>{value}</span>
        <button onClick={() => copy(id, value)} style={{ flexShrink: 0, display: 'inline-flex', alignItems: 'center', gap: 5,
          border: 'none', cursor: 'pointer', borderRadius: 8, padding: '7px 11px',
          background: copied === id ? 'var(--es-success)' : 'var(--es-fill)', color: copied === id ? '#fff' : 'var(--es-ink-2)',
          font: 'var(--es-t-caption-2)', fontWeight: 700 }}>
          <Ic n={copied === id ? 'check' : 'doc'} s={14} />{copied === id ? '복사됨' : '복사'}
        </button>
      </div>
    </div>
  );
  return (
    <React.Fragment>
      <div style={{ flexShrink: 0, padding: '10px 20px 4px', display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative' }}>
        <div style={{ width: 38, height: 5, borderRadius: 3, background: 'var(--es-fill-press)' }} />
        <button onClick={onClose} style={{ position: 'absolute', right: 16, top: 8, background: 'var(--es-fill)', border: 'none',
          width: 30, height: 30, borderRadius: '50%', display: 'grid', placeItems: 'center', color: 'var(--es-ink-2)', cursor: 'pointer' }}>
          <Ic n="xmark" s={15} />
        </button>
      </div>
      <div style={{ flex: 1, overflow: 'auto', padding: '14px 24px 32px', display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
        <div className="es-title-3" style={{ marginBottom: 4 }}>QR로 받기</div>
        <div style={{ width: 180, height: 180, borderRadius: 'var(--es-r-lg)', background: '#fff', border: '0.5px solid var(--es-separator)',
          boxShadow: 'var(--es-shadow-1)', display: 'grid', placeItems: 'center', color: 'var(--es-ink-3)', marginTop: 14 }}>
          <Ic n="qrcode" s={104} sw={1.3} />
        </div>
        <p className="es-subhead es-ink-2" style={{ marginTop: 16, textAlign: 'center', lineHeight: 1.5 }}>
          QR을 스캔하면 주소와 태그가 자동으로 입력돼요.
        </p>
        <div style={{ width: '100%' }}>
          <Row label="지갑 주소" value={addr} id="addr" />
          <Row label="Destination Tag" value={tag} id="tag" />
        </div>
        <p className="es-caption es-ink-3" style={{ marginTop: 12, textAlign: 'center', lineHeight: 1.5 }}>
          거래소 지갑에서 받을 때는 Destination Tag를 반드시 함께 입력해 주세요.
        </p>
      </div>
    </React.Fragment>
  );
}

// ── 보내기 (XRP 송신) ──
function SendScreen({ balance, onClose }) {
  const [state, setState] = React.useState('form'); // form | done
  const [to, setTo] = React.useState('');
  const [tag, setTag] = React.useState('');
  const [amount, setAmount] = React.useState('');
  const [err, setErr] = React.useState('');
  const send = () => {
    if (to.trim().length < 20 || !to.trim().startsWith('r')) { setErr('올바른 XRPL 주소를 입력해 주세요.'); return; }
    const n = Number(amount);
    if (!n || n <= 0) { setErr('보낼 수량을 입력해 주세요.'); return; }
    setErr(''); setState('done');
  };
  return (
    <React.Fragment>
      <MtNav title="보내기" left={<button className="es-navbar__btn" style={{ color: 'var(--es-ink)' }} onClick={onClose}><Ic n="chevron-left" s={24} /></button>} />
      <div style={{ flex: 1, overflow: 'auto', padding: '20px 24px' }}>
        {state === 'form' ? (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
            <div className="es-field">
              <label className="es-label">받는 주소</label>
              <input className={'es-input' + (err && !to ? ' es-input--invalid' : '')} placeholder="r..." value={to}
                onChange={(e) => { setTo(e.target.value); if (err) setErr(''); }} style={{ fontSize: 15 }} />
            </div>
            <div className="es-field">
              <label className="es-label">Destination Tag <span className="es-ink-3" style={{ fontWeight: 400 }}>(거래소로 보낼 때 필수)</span></label>
              <input className="es-input" type="number" inputMode="numeric" placeholder="없으면 비워두세요" value={tag}
                onChange={(e) => setTag(e.target.value)} style={{ fontSize: 15 }} />
            </div>
            <div className="es-field">
              <label className="es-label">수량 (XRP)</label>
              <input className="es-input" type="number" inputMode="decimal" placeholder="0.0" value={amount}
                onChange={(e) => { setAmount(e.target.value); if (err) setErr(''); }} style={{ fontSize: 15 }} />
              <span className="es-help">보유 잔액 {balance} XRP</span>
            </div>
            {err && <span className="es-help es-help--error">{err}</span>}
          </div>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center', marginTop: 40 }}>
            <div style={{ width: 64, height: 64, borderRadius: '50%', background: 'var(--es-success-soft, #E4F0E8)',
              color: 'var(--es-success)', display: 'grid', placeItems: 'center', marginBottom: 16 }}>
              <Ic n="check" s={32} />
            </div>
            <div className="es-title-2">보냈어요</div>
            <p className="es-subhead es-ink-2" style={{ marginTop: 8, lineHeight: 1.5 }}>
              {amount} XRP를 보냈습니다.{tag && <> Destination Tag {tag}</>}<br />처리에는 몇 초 정도 걸릴 수 있어요.
            </p>
          </div>
        )}
      </div>
      <div style={{ flexShrink: 0, padding: '12px 24px 34px', borderTop: '0.5px solid var(--es-separator)' }}>
        {state === 'form'
          ? <button className="es-btn es-btn--primary es-btn--block" onClick={send}>보내기</button>
          : <button className="es-btn es-btn--primary es-btn--block" onClick={onClose}>확인</button>}
      </div>
    </React.Fragment>
  );
}

// ── 거래 내역 (EVS-iOS 013) ──
function TransactionHistoryScreen({ onClose }) {
  const txs = [
    { seller: '김서진', buyer: '박서린', nft: '#1740', t: '청록 변주', amount: '1,850', ts: '2026.07.12 14:03' },
    { seller: '박서린', buyer: '한도윤', nft: '#5102', t: '겹의 시간', amount: '2,100', ts: '2026.07.08 09:41' },
    { seller: '문지호', buyer: '박서린', nft: '#0932', t: '겨울 창', amount: '3,050', ts: '2026.06.29 21:17' },
    { seller: '박서린', buyer: '이정안', nft: '#2910', t: '심해의 빛', amount: '4,400', ts: '2026.06.15 11:52' },
  ];
  return (
    <>
      <MtNav title="거래 내역" left={<NavIcon n="chevron-left" onClick={onClose} />} />
      <Scroll>
        <div style={{ padding: '16px 16px 24px' }}>
          <div className="es-list-header">전체 · {txs.length}건</div>
          <div className="es-list">
            {txs.map((x, i) => (
              <div key={i} className="es-row" style={{ alignItems: 'flex-start', padding: '13px 14px' }}>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 0 }}>
                    <span className="es-subhead" style={{ fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{x.t}</span>
                  </div>
                  <div className="es-footnote es-ink-3" style={{ marginTop: 3, display: 'flex', alignItems: 'center', gap: 5 }}>
                    {x.seller} <Ic n="arrow-right" s={12} /> {x.buyer}
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 6 }}>
                    <span className="es-caption es-ink-3 es-mono">NFT {x.nft}</span>
                    <span className="es-caption es-ink-4">·</span>
                    <span className="es-caption es-ink-3 es-mono">{x.ts}</span>
                  </div>
                </div>
                <div className="es-subhead es-mono es-price" style={{ fontWeight: 700, flexShrink: 0, marginLeft: 8 }}>{x.amount}<span className="es-caption es-ink-3" style={{ fontWeight: 400 }}> XRP</span></div>
              </div>
            ))}
          </div>
        </div>
      </Scroll>
    </>
  );
}

// ── 정산 내역 (EVS-iOS 013) ──
function SettlementHistoryScreen({ onClose }) {
  const items = [
    { type: '판매', bg: 'var(--es-green)', nftId: '000B1F5102A93CE1B8D4F6A2C7CF', t: '겹의 시간', creator: '박서린', year: '2015', ts: '2026.07.08 09:41', amount: '2,047.50', positive: true },
    { type: '구매', bg: 'var(--es-ink-2)', nftId: '0004A20932F81D3C5E9B0A7F41DE', t: '겨울 창', creator: '문지호', year: '2018', ts: '2026.07.05 13:12', amount: '3,050.00', positive: false },
    { type: '라이선싱', bg: 'var(--es-sage)', nftId: '00072910B4E8A1F03D6C5B2E9A81', t: '심해의 빛', creator: '이정안', year: '2015', ts: '2026.06.22 10:05', amount: '180.00', positive: true },
    { type: '판매', bg: 'var(--es-green)', nftId: '0004A20932F81D3C5E9B0A7F41DE', t: '겨울 창', creator: '문지호', year: '2018', ts: '2026.06.15 11:52', amount: '2,975.00', positive: true },
  ];
  return (
    <>
      <MtNav title="정산 내역" left={<NavIcon n="chevron-left" onClick={onClose} />} />
      <Scroll>
        <div style={{ padding: '16px 16px 24px' }}>
          <div className="es-list-header">전체 · {items.length}건</div>
          <div className="es-list">
            {items.map((x, i) => (
              <div key={i} className="es-row" style={{ alignItems: 'flex-start', padding: '18px 14px' }}>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 0, flexWrap: 'wrap' }}>
                    <span className="es-badge" style={{ background: x.bg, color: '#fff', flexShrink: 0 }}>{x.type}</span>
                    <span className="es-subhead" style={{ fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', minWidth: 0 }}>{x.t}</span>
                    <span className="es-subhead es-ink-3" style={{ fontWeight: 400, whiteSpace: 'nowrap', flexShrink: 0 }}>({x.year})</span>
                  </div>
                  <div className="es-caption es-ink-3" style={{ marginTop: 6, whiteSpace: 'nowrap' }}>· 원작자: {x.creator}</div>
                  <div className="es-caption es-ink-3 es-mono" style={{ marginTop: 3, whiteSpace: 'nowrap' }}>· NFT: #{x.nftId.slice(0,4)}...{x.nftId.slice(-4)}</div>
                  <div className="es-caption es-ink-3 es-mono" style={{ marginTop: 3, whiteSpace: 'nowrap' }}>· 거래일: {x.ts}</div>
                </div>
                <div className="es-subhead es-mono es-price" style={{ fontWeight: 700, color: x.positive ? 'var(--es-success)' : 'var(--es-ink)', flexShrink: 0, marginLeft: 8 }}>{x.positive ? '+' : '−'}{x.amount}<span className="es-caption es-ink-3" style={{ fontWeight: 400 }}> XRP</span></div>
              </div>
            ))}
          </div>
        </div>
      </Scroll>
    </>
  );
}

const MAIN_SCREENS = {
  dashboard: DashboardScreen,
  register: RegisterScreen,
  verify: VerifyScreen,
  my: MyPageScreen,
};

Object.assign(window, {
  DashboardScreen, RegisterScreen, VerifyScreen, MyPageScreen,
  MainTabBar, MAIN_SCREENS, SettlementHistoryScreen,
});
