// EVERSEAL — Main VC Flow · Sub-screens
// Asset Detail / Trading / Licensing / NFT Burn / Registration form + done / Verify result
// Self-contained (own helpers) — load WITHOUT main-tabs.jsx to avoid name clashes.
// Requires icons.js (esIcon) + ios-frame.jsx (IOSDevice)
// Grounded in EVS-iOS 005/006/011/012 + To-Be 수익모델·보안 설계

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

// one-time keyframe inject (spinner used by WalletManageScreen)
if (typeof document !== 'undefined' && !document.getElementById('es-sub-kf')) {
  const st = document.createElement('style');
  st.id = 'es-sub-kf';
  st.textContent = '@keyframes esSubSpin{to{transform:rotate(360deg)}}';
  document.head.appendChild(st);
}

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

// 지갑 주소 (진한 카드용) · 가운데 …축약 · 1줄 고정 · 복사 + 피드백
function WalletAddrLine({ addr, head = 10, tail = 6 }) {
  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: 8, marginTop: 3 }}>
      <span className="es-mono es-subhead" style={{ color: '#fff', fontWeight: 600,
        whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', flex: 1, minWidth: 0 }}>{short}</span>
      <button type="button" onClick={copy} aria-label="지갑 주소 복사" style={{
        flexShrink: 0, display: 'inline-flex', alignItems: 'center', gap: 4, border: 'none',
        background: copied ? 'rgba(122,184,148,0.22)' : 'rgba(255,255,255,0.12)', cursor: 'pointer',
        padding: '5px 9px', borderRadius: 8, fontFamily: 'inherit',
        color: copied ? 'var(--es-bronze-tint)' : 'rgba(255,255,255,0.85)', transition: 'background .15s' }}>
        <Ic n={copied ? 'check' : 'doc'} s={15} />
        <span className="es-caption" style={{ fontWeight: 600, color: 'inherit' }}>{copied ? '복사됨' : '복사'}</span>
      </button>
    </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 ART = {
  dawn:   ['#C9BBA0', '#7C6A48'],
  layers: ['#D8C2C0', '#7A5556'],
  moon:   ['#E7E2D6', '#A89B7C'],
  abyss:  ['#3A4A63', '#0E1726'],
  blue:   ['#9FB4C9', '#3C566E'],
};

// push-style nav bar (back chevron + centered title)
function PushNav({ title, onBack, right, dark, hideBack }) {
  const c = 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: `0.5px solid ${dark ? 'rgba(255,255,255,0.12)' : 'var(--es-separator)'}`,
      position: 'relative', zIndex: 5,
    }}>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr auto 1fr', alignItems: 'center',
        gap: 8, padding: '6px 14px 8px', minHeight: 44 }}>
        <div style={{ justifySelf: 'start' }}>
          {!hideBack && <button className="es-navbar__btn" onClick={onBack} style={{ color: c }}><Ic n="chevron-left" s={26} /></button>}
        </div>
        <div className="es-headline" style={{ color: c, whiteSpace: 'nowrap' }}>{title}</div>
        <div style={{ justifySelf: 'end', display: 'flex', gap: 2 }}>{right}</div>
      </div>
    </div>
  );
}

const StickyBar = ({ children, dark }) => (
  <div style={{ flexShrink: 0, padding: '12px 16px 30px',
    background: dark ? 'rgba(18,28,21,0.92)' : 'rgba(255,255,255,0.92)',
    backdropFilter: 'blur(20px)', WebkitBackdropFilter: 'blur(20px)',
    borderTop: `0.5px solid ${dark ? 'rgba(255,255,255,0.1)' : 'var(--es-separator)'}` }}>
    {children}
  </div>
);

const InfoTip = ({ text }) => {
  const [open, setOpen] = React.useState(false);
  return (
    <span style={{ position: 'relative', display: 'inline-flex', verticalAlign: 'middle' }}>
      <button type="button" aria-label="설명" onClick={(e) => { e.stopPropagation(); setOpen(o => !o); }}
        style={{ display: 'inline-flex', border: 'none', background: 'transparent', padding: 0, marginLeft: 4,
          cursor: 'pointer', color: open ? 'var(--es-green)' : 'var(--es-ink-4)' }}>
        <Ic n="info" s={15} />
      </button>
      {open && (
        <React.Fragment>
          <span onClick={(e) => { e.stopPropagation(); setOpen(false); }}
            style={{ position: 'fixed', inset: 0, zIndex: 900 }} />
          <span style={{ position: 'absolute', bottom: 'calc(100% + 8px)', left: '50%', transform: 'translateX(-50%)',
            zIndex: 901, width: 180, background: 'var(--es-ink)', color: '#fff', borderRadius: 10,
            padding: '9px 11px', boxShadow: '0 6px 22px rgba(0,0,0,0.28)', textAlign: 'left' }}>
            <span className="es-caption" style={{ color: '#fff', lineHeight: 1.45, display: 'block', fontWeight: 500 }}>{text}</span>
            <span style={{ position: 'absolute', top: '100%', left: '50%', transform: 'translateX(-50%)',
              width: 0, height: 0, borderLeft: '6px solid transparent', borderRight: '6px solid transparent',
              borderTop: '6px solid var(--es-ink)' }} />
          </span>
        </React.Fragment>
      )}
    </span>
  );
};

const FieldRow = ({ k, v, mono, last, strong, info }) => (
  <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12, padding: '9px 0',
    borderTop: last === 'first' ? 'none' : '0.5px solid var(--es-separator)' }}>
    <span className="es-subhead es-ink-2" style={{ display: 'inline-flex', alignItems: 'center' }}>
      {k}{info && <InfoTip text={info} />}
    </span>
    <span className={'es-subhead' + (mono ? ' es-mono' : '')} style={{ fontWeight: strong ? 700 : 600, textAlign: 'right' }}>{v}</span>
  </div>
);

// ═════════════════════════════════════════════════════════
//  ASSET DETAIL  (작품 상세 · EVS-iOS 011)
// ═════════════════════════════════════════════════════════
function AssetDetailScreen() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', color: 'var(--es-ink)', background: 'var(--es-bg)' }}>
      <PushNav title="작품 상세" onBack={() => {}}
        right={<><button className="es-navbar__btn" style={{ color: 'var(--es-ink)' }}><Ic n="share" s={21} /></button>
          <button className="es-navbar__btn" style={{ color: 'var(--es-ink)' }}><Ic n="ellipsis" s={22} /></button></>} />
      <Scroll>
        <Canvas img="assets/dawn-still-life.jpg" h={300}>
          <span style={{ position: 'absolute', bottom: 12, left: 16 }}>
            <span className="es-badge es-badge--verified"><Ic n="shield-check" s={12} />정품 인증</span>
          </span>
          <span className="es-badge es-badge--neutral" style={{ position: 'absolute', bottom: 12, right: 16, background: 'rgba(255,255,255,0.92)' }}>에디션 12 / 50</span>
        </Canvas>

        <div style={{ padding: '20px 16px 4px' }}>
          <div className="es-footnote es-ink-3">2025 · 캔버스에 유채 · 72.7 × 60.6 cm</div>
          <div className="es-title-1" style={{ marginTop: 4 }}>새벽의 정물 No.3</div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 16 }}>
            <div className="es-avatar" style={{ width: 40, height: 40, background: 'var(--es-green-deep)', color: 'var(--es-bronze-tint)' }}>
              <Ic n="brush" s={20} />
            </div>
            <div style={{ flex: 1 }}>
              <div className="es-subhead" style={{ fontWeight: 600, display: 'flex', alignItems: 'center', gap: 5 }}>
                박서린 <Ic n="shield-check" s={14} style={{ color: 'var(--es-bronze)' }} />
              </div>
              <div className="es-caption es-ink-3">인증 작가 · 소유자 본인</div>
            </div>
          </div>
        </div>

        {/* parties · 발행자 · 원작자 · 현재 소유자 */}
        <div style={{ padding: '18px 16px 0' }}>
          <div className="es-title-3" style={{ marginBottom: 10 }}>작품 관계자</div>
          <div className="es-card" style={{ padding: '4px 16px', boxShadow: 'var(--es-shadow-1)' }}>
            {[
              ['발행자', '박서린', 'rN7n…fzRH', 'seal'],
              ['원작자', '박서린', '인증 작가', 'brush'],
              ['현재 소유자', '박서린', '본인 보관', 'person'],
            ].map(([role, name, sub, ic], i) => (
              <div key={role} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 0',
                borderTop: i ? '0.5px solid var(--es-separator)' : 'none' }}>
                <div className="es-avatar" style={{ width: 38, height: 38, background: 'var(--es-green-deep)', color: 'var(--es-bronze-tint)' }}>
                  <Ic n={ic} s={18} />
                </div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div className="es-caption es-ink-3">{role}</div>
                  <div className="es-subhead" style={{ fontWeight: 600, display: 'flex', alignItems: 'center', gap: 5 }}>
                    {name}<Ic n="shield-check" s={13} style={{ color: 'var(--es-bronze)' }} />
                  </div>
                </div>
                <div className="es-caption es-ink-3 es-mono" style={{ flexShrink: 0 }}>{sub}</div>
              </div>
            ))}
          </div>
        </div>

        {/* 현재 거래 · XRPL 판매 제안 진행 중 */}
        <div style={{ padding: '18px 16px 0' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>
            <div className="es-title-3">현재 거래</div>
            <span className="es-badge es-badge--info">거래중</span>
          </div>
          <div className="es-card" style={{ padding: '4px 16px', boxShadow: 'var(--es-shadow-1)' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 0' }}>
              <div className="es-avatar" style={{ width: 38, height: 38, background: 'var(--es-blue-soft)', color: 'var(--es-blue)' }}>
                <Ic n="person" s={18} />
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div className="es-caption es-ink-3">잠재 바이어</div>
                <div className="es-subhead" style={{ fontWeight: 600 }}>김도윤</div>
              </div>
              <div className="es-caption es-ink-3 es-mono" style={{ flexShrink: 0 }}>rDoY…4fzRH</div>
            </div>
            <FieldRow k="제안 가격" v="1,200 XRP" mono strong />
            <FieldRow k="제안 일자" v="2026.07.05" />
          </div>
        </div>

        {/* ownership / provenance */}
        <div style={{ padding: '20px 16px 0' }}>
          <div className="es-title-3" style={{ marginBottom: 10 }}>소유 · 거래 이력</div>
          <div style={{ position: 'relative', paddingLeft: 4 }}>
            {[
              ['작품 등록 · NFT 발행', '2024.03.12 · 박서린(작가)', 'seal', 'var(--es-green)'],
              ['1차 판매', '2024.09.02 · 2,800 XRP', 'arrow-up-right', 'var(--es-bronze)'],
              ['소유권 이전 (현재)', '2025.05.20 · 박서린 보관', 'person', 'var(--es-ink-2)'],
            ].map(([t, d, ic, col], i, arr) => (
              <div key={i} style={{ display: 'flex', gap: 13, paddingBottom: i < arr.length - 1 ? 16 : 0, position: 'relative' }}>
                {i < arr.length - 1 && <div style={{ position: 'absolute', left: 15, top: 34, bottom: 0, width: 2, background: 'var(--es-separator-strong)' }} />}
                <div style={{ width: 32, height: 32, borderRadius: '50%', flexShrink: 0, zIndex: 1, background: 'var(--es-surface)',
                  border: `1.5px solid ${col}`, display: 'grid', placeItems: 'center', color: col }}>
                  <Ic n={ic} s={16} />
                </div>
                <div style={{ paddingTop: 4 }}>
                  <div className="es-subhead" style={{ fontWeight: 600 }}>{t}</div>
                  <div className="es-caption es-ink-3" style={{ marginTop: 1 }}>{d}</div>
                </div>
              </div>
            ))}
          </div>
        </div>

        {/* manage (burn) */}
      </Scroll>

      <StickyBar>
        <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
          <div>
            <div className="es-caption es-ink-3">추정 시세</div>
            <div className="es-title-3 es-price">3,100 <span className="es-subhead es-ink-3">XRP</span></div>
          </div>
          <button className="es-btn es-btn--primary" style={{ flex: 1 }}><Ic n="tag" s={18} />거래하기</button>
        </div>
      </StickyBar>
    </div>
  );
}

// ═════════════════════════════════════════════════════════
//  TRADING  (거래하기 · EVS-iOS 012)
// ═════════════════════════════════════════════════════════
function TradingScreen() {
  const [mode, setMode] = React.useState('판매');
  const [price, setPrice] = React.useState('3,200');
  const [stage, setStage] = React.useState('form'); // form | processing
  const num = parseFloat(String(price).replace(/,/g, '')) || 0;
  const fee = Math.round(num * 0.025);
  const royalty = Math.round(num * 0.10);
  const net = num - fee - royalty;
  const krw = (n) => '₩' + Math.round(n * 1850).toLocaleString();
  const fmt = (n) => n.toLocaleString();

  const submit = () => {
    setStage('processing');
    setTimeout(() => setStage('form'), 1800); // demo loop — 실제로는 완료 후 다음 스텝(판매 대상 지정)으로 push
  };

  if (stage === 'processing') {
    const label = mode === '판매' ? '판매 등록' : '양도 등록';
    return (
      <div style={{ display: 'flex', flexDirection: 'column', height: '100%', color: 'var(--es-ink)', background: 'var(--es-bg)', position: 'relative', overflow: 'hidden' }}>
        <style>{'@keyframes esSpin{to{transform:rotate(360deg)}}'}</style>
        <PushNav title="거래 등록" onBack={() => {}} />
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', padding: '0 32px' }}>
          <svg width="52" height="52" viewBox="0 0 52 52" style={{ animation: 'esSpin .9s linear infinite' }}>
            <circle cx="26" cy="26" r="22" fill="none" stroke="var(--es-fill)" strokeWidth="4" />
            <circle cx="26" cy="26" r="22" fill="none" stroke="var(--es-gold)" strokeWidth="4"
              strokeLinecap="round" strokeDasharray="138" strokeDashoffset="104" />
          </svg>
          <div className="es-headline" style={{ marginTop: 20 }}>{label}을 처리하고 있어요</div>
          <p className="es-subhead es-ink-3" style={{ marginTop: 6 }}>수수료를 정산하고 XRPL 원장에 기록 중…</p>
          <div className="es-card" style={{ width: '100%', marginTop: 28, padding: '4px 16px', boxShadow: 'var(--es-shadow-1)', textAlign: 'left' }}>
            <FieldRow last="first" k={mode === '판매' ? '판매가' : '평가액'} v={`${fmt(num)} XRP`} mono />
            <FieldRow k="정산 예상 수령액" v={`${fmt(net)} XRP`} mono strong />
          </div>
        </div>
      </div>
    );
  }

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', color: 'var(--es-ink)', background: 'var(--es-bg-grouped)' }}>
      <PushNav title="거래 등록" onBack={() => {}} />
      <Scroll>
        {/* artwork mini */}
        <div style={{ padding: '14px 16px 0' }}>
          <div className="es-card es-card--flat" style={{ display: 'flex', alignItems: 'center', gap: 12, padding: 10 }}>
            <Canvas img="assets/dawn-still-life.jpg" h={52} style={{ width: 52, borderRadius: 10, flexShrink: 0 }} />
            <div style={{ flex: 1 }}>
              <div className="es-subhead" style={{ fontWeight: 600 }}>새벽의 정물 No.3</div>
              <div className="es-caption es-ink-3" style={{ marginTop: 1 }}>박서린 · 에디션 12/50 · NFT #4821</div>
            </div>
            <span className="es-badge es-badge--verified" style={{ padding: '3px 7px' }}><Ic n="shield-check" s={11} /></span>
          </div>
        </div>

        {/* mode */}
        <div style={{ padding: '18px 16px 0' }}>
          <div className="es-segment">
            {['판매', '이전(양도)'].map(t => (
              <button key={t} className="es-segment__item" aria-selected={t === mode} onClick={() => setMode(t)}>{t}</button>
            ))}
          </div>
        </div>

        {/* price */}
        <div style={{ padding: '20px 16px 0' }}>
          <div className="es-label" style={{ marginBottom: 8 }}>{mode === '판매' ? '판매 가격' : '양도 평가액'}</div>
          <div style={{ background: 'var(--es-surface)', borderRadius: 'var(--es-r-lg)', border: '1.5px solid var(--es-green)', padding: '16px 18px', display: 'flex', alignItems: 'baseline', gap: 8 }}>
            <input value={price} onChange={e => setPrice(e.target.value)} inputMode="decimal"
              style={{ border: 'none', outline: 'none', font: 'var(--es-t-title-1)', letterSpacing: '-0.4px', width: '100%', background: 'transparent', color: 'var(--es-ink)' }} />
            <span className="es-title-3 es-ink-3" style={{ flexShrink: 0 }}>XRP</span>
          </div>
          <div className="es-footnote es-ink-3" style={{ marginTop: 6 }}>≈ {krw(num)}</div>
        </div>

        {/* fee breakdown */}
        <div style={{ padding: '20px 16px 8px' }}>
          <div className="es-list-header">정산 예상</div>
          <div className="es-card" style={{ padding: '4px 16px', boxShadow: 'var(--es-shadow-1)', overflow: 'visible' }}>
            <FieldRow last="first" k={mode === '판매' ? '판매가' : '평가액'} v={`${fmt(num)} XRP`} mono />
            <FieldRow k="플랫폼 수수료 (2.5%)" v={`− ${fmt(fee)} XRP`} mono />
            <FieldRow k="작가 로열티 (10%)" v={`− ${fmt(royalty)} XRP`} mono info="작품을 처음 만든 작가에게 돌아가는 수수료예요. 재판매될 때마다 자동 정산돼요." />
            <FieldRow k="정산 예상 수령액" v={`${fmt(net)} XRP`} mono strong />
          </div>
          <div style={{ display: 'flex', gap: 7, padding: '12px 4px 0', color: 'var(--es-ink-3)' }}>
            <Ic n="info" s={15} style={{ flexShrink: 0, marginTop: 1 }} />
            <span className="es-footnote es-ink-3" style={{ lineHeight: 1.45 }}>
              2차 판매 로열티는 NFT 메타데이터 정책에 따라 자동 분배되며, 정산은 서버 검증 후 XRPL 원장에 기록됩니다.
            </span>
          </div>
        </div>
      </Scroll>

      <StickyBar>
        <button className="es-btn es-btn--primary es-btn--block" onClick={submit}>{mode === '판매' ? '판매 등록' : '양도 등록'}</button>
      </StickyBar>
    </div>
  );
}

// ═════════════════════════════════════════════════════════
//  SELL OFFER  (판매 대상 지정 · NFTokenCreateOffer + Destination)
//  TradeViewController 다음 단계
// ═════════════════════════════════════════════════════════
// mock 회원 DB — 이름 검색 시 서버에서 조회하는 구조를 표현
const ES_MEMBERS = [
  { name: '김도윤', role: '컬렉터 · 인증회원', addr: 'rDoYn7kQm2vT8xLpZa3bXcW9uHsNq4fzRH', color: '#4B6D5A' },
  { name: '이서준 갤러리', role: '갤러리 · 서울', addr: 'rGa11eryS3jNv8kQm2xLpZa3bXcW9uHsNq', color: '#7A5A3C' },
  { name: '박하늘', role: '투자자', addr: 'rHaNu1x8kQm2vT8xLpZa3bXcW9uHsNq4fz', color: '#3C5A7A' },
  { name: '정예린', role: '컬렉터', addr: 'rYeR1n2vT8xLpZa3bXcW9uHsNq4fzRHkQm', color: '#6B4B6D' },
  { name: '최민서', role: '컬렉터 · 인증회원', addr: 'rM1nSeo8kQm2vT8xLpZa3bXcW9uHsNq4fz', color: '#5A6B3C' },
  { name: '한지우 아트', role: '갤러리 · 부산', addr: 'rJiWu2vT8xLpZa3bXcW9uHsNq4fzRHkQm2', color: '#8A5A5A' },
  { name: '오세훈', role: '투자자', addr: 'rSeHun8kQm2vT8xLpZa3bXcW9uHsNq4fzR', color: '#3C6D6D' },
];
function isXrplAddr(s) { return /^r[1-9A-HJ-NP-Za-km-z]{24,34}$/.test(s.trim()); }
function shortAddr(a) { return a.length > 16 ? a.slice(0, 8) + '…' + a.slice(-5) : a; }

function SellOfferScreen() {
  const NET = 2808;                    // 최종 예상 수령액 (TradeVC 정산 결과)
  const [query, setQuery] = React.useState('');
  const [picked, setPicked] = React.useState(null);   // 선택된 판매 대상
  const [searching, setSearching] = React.useState(false); // 검색 오버레이 열림
  const [expiry, setExpiry] = React.useState('7일');
  const [confirming, setConfirming] = React.useState(false); // iOS 확인 알럿
  const [stage, setStage] = React.useState('form');          // form | processing | done
  const krw = (n) => '₩' + Math.round(n * 1850).toLocaleString();

  const submit = () => {
    setConfirming(false);
    setStage('processing');
    setTimeout(() => setStage('done'), 1400);
  };
  const targetName = picked ? (picked.member ? picked.member.name : shortAddr(picked.addr)) : '';

  const q = query.trim();
  const rawMatch = isXrplAddr(q);
  const results = q.length >= 1
    ? ES_MEMBERS.filter(m => m.name.includes(q) || m.addr.toLowerCase().startsWith(q.toLowerCase()))
    : ES_MEMBERS;
  const canSubmit = !!picked;
  const choose = (sel) => { setPicked(sel); setSearching(false); };

  const Avatar = ({ m, s = 40 }) => (
    <div style={{ width: s, height: s, borderRadius: '50%', flexShrink: 0, background: m.color,
      color: '#fff', display: 'grid', placeItems: 'center', fontWeight: 700, fontSize: s * 0.42 }}>
      {m.name[0]}
    </div>
  );

  // ── 처리 중 · 완료 화면 ──
  if (stage === 'processing' || stage === 'done') {
    const isDone = stage === 'done';
    return (
      <div style={{ display: 'flex', flexDirection: 'column', height: '100%', color: 'var(--es-ink)', background: 'var(--es-bg)', position: 'relative', overflow: 'hidden' }}>
        <style>{'@keyframes esSpin{to{transform:rotate(360deg)}}@keyframes esPop{0%{transform:scale(.6);opacity:0}60%{transform:scale(1.08)}100%{transform:scale(1);opacity:1}}'}</style>
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', padding: '0 32px' }}>
          {isDone ? (
            <React.Fragment>
              <div style={{ width: 84, height: 84, borderRadius: '50%', background: 'var(--es-success-soft, #E4F0E8)',
                color: 'var(--es-success)', display: 'grid', placeItems: 'center', animation: 'esPop .45s cubic-bezier(.32,.72,0,1) both' }}>
                <Ic n="check" s={46} sw={2.4} />
              </div>
              <div className="es-title-2" style={{ marginTop: 22 }}>판매 제안이 등록되었어요</div>
              <p className="es-subhead es-ink-2" style={{ marginTop: 8, lineHeight: 1.55 }}>
                {targetName ? <b style={{ color: 'var(--es-ink)' }}>{targetName}</b> : '지정한 상대'}님에게 판매 제안을 보냈어요.<br />상대가 수락하면 소유권이 이전됩니다.
              </p>
              <div className="es-card" style={{ width: '100%', marginTop: 24, padding: '4px 16px', boxShadow: 'var(--es-shadow-1)', textAlign: 'left' }}>
                <FieldRow last="first" k="판매 대상" v={targetName} />
                <FieldRow k="수령 예상액" v={`${NET.toLocaleString()} XRP`} mono />
                <FieldRow k="제안 만료" v={expiry} />
                <FieldRow k="상태" v="수락 대기 중" />
              </div>
            </React.Fragment>
          ) : (
            <React.Fragment>
              <svg width="52" height="52" viewBox="0 0 52 52" style={{ animation: 'esSpin .9s linear infinite' }}>
                <circle cx="26" cy="26" r="22" fill="none" stroke="var(--es-fill)" strokeWidth="4" />
                <circle cx="26" cy="26" r="22" fill="none" stroke="var(--es-gold)" strokeWidth="4"
                  strokeLinecap="round" strokeDasharray="138" strokeDashoffset="104" />
              </svg>
              <div className="es-headline" style={{ marginTop: 20 }}>판매 제안을 등록하고 있어요</div>
              <p className="es-subhead es-ink-3" style={{ marginTop: 6 }}>XRPL 원장에 안전하게 기록 중…</p>
            </React.Fragment>
          )}
        </div>
        {isDone && (
          <div style={{ flexShrink: 0, padding: '0 20px 28px', display: 'flex', flexDirection: 'column', gap: 10 }}>
            <button className="es-btn es-btn--primary es-btn--block"
              onClick={() => { setStage('form'); setPicked(null); setQuery(''); setExpiry('7일'); }}>
              <Ic n="compass" s={18} />대시보드로 이동
            </button>
            <button className="es-btn es-btn--ghost es-btn--block" style={{ color: 'var(--es-ink-2)' }}>판매 내역 보기</button>
          </div>
        )}
      </div>
    );
  }

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', color: 'var(--es-ink)', background: 'var(--es-bg-grouped)', position: 'relative', overflow: 'hidden' }}>
      <PushNav title="거래 상세" onBack={() => {}} />
      <Scroll>
        {/* price summary */}
        <div style={{ padding: '16px 16px 0' }}>
          <div className="es-card" style={{ padding: '14px 16px', boxShadow: 'var(--es-shadow-1)' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
              <Canvas img="assets/dawn-still-life.jpg" h={44} style={{ width: 44, borderRadius: 9, flexShrink: 0 }} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div className="es-subhead" style={{ fontWeight: 600 }}>새벽의 정물 No.3</div>
                <div className="es-caption es-ink-3" style={{ marginTop: 1 }}>박서린 · 에디션 12/50 · NFT #4821</div>
              </div>
            </div>
            <div style={{ height: '0.5px', background: 'var(--es-separator)', margin: '13px 0' }} />
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
              <span className="es-subhead es-ink-2">최종 예상 수령액</span>
              <span className="es-mono" style={{ fontWeight: 700 }}>
                <span className="es-title-3" style={{ fontWeight: 700 }}>{NET.toLocaleString()}</span>
                <span className="es-subhead es-ink-2" style={{ marginLeft: 4 }}>XRP</span>
              </span>
            </div>
            <div className="es-caption es-ink-3" style={{ textAlign: 'right', marginTop: 2 }}>≈ {krw(NET)}</div>
          </div>
        </div>

        {/* recipient */}
        <div style={{ padding: '22px 16px 0' }}>
            <div className="es-list-header">판매 대상</div>

            {picked ? (
              <div className="es-card" style={{ padding: '12px 14px', boxShadow: 'var(--es-shadow-1)',
                display: 'flex', alignItems: 'center', gap: 12, border: '1.5px solid var(--es-green)' }}>
                {picked.member ? <Avatar m={picked.member} />
                  : <div style={{ width: 40, height: 40, borderRadius: '50%', background: 'var(--es-surface-2)',
                      color: 'var(--es-bronze)', display: 'grid', placeItems: 'center', flexShrink: 0 }}><Ic n="wallet" s={20} /></div>}
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div className="es-subhead" style={{ fontWeight: 600 }}>{picked.member ? picked.member.name : '직접 입력한 지갑'}</div>
                  <div className="es-caption es-ink-3 es-mono" style={{ marginTop: 1, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{shortAddr(picked.addr)}</div>
                </div>
                <button onClick={() => { setSearching(true); }} aria-label="변경" className="es-subhead"
                  style={{ border: 'none', background: 'transparent', color: 'var(--es-green)', fontWeight: 600, cursor: 'pointer', padding: '4px 2px', fontFamily: 'inherit' }}>
                  변경
                </button>
              </div>
            ) : (
              <button onClick={() => { setQuery(''); setSearching(true); }}
                style={{ width: '100%', display: 'flex', alignItems: 'center', gap: 10, padding: '13px 14px',
                  borderRadius: 'var(--es-r-lg)', border: '1px solid var(--es-separator-strong)', background: 'var(--es-surface)',
                  cursor: 'pointer', textAlign: 'left', boxShadow: 'var(--es-shadow-1)' }}>
                <Ic n="search" s={19} style={{ color: 'var(--es-ink-3)', flexShrink: 0 }} />
                <span className="es-subhead es-ink-3" style={{ flex: 1 }}>이름 또는 지갑 주소로 검색</span>
                <Ic n="chevron-right" s={17} style={{ color: 'var(--es-ink-4)' }} />
              </button>
            )}
          </div>

        {/* expiration */}
        <div style={{ padding: '22px 16px 0' }}>
          <div className="es-list-header">제안 만료 <span className="es-ink-3" style={{ fontWeight: 400 }}>· Expiration</span></div>
          <div style={{ display: 'flex', gap: 8 }}>
            {['24시간', '7일', '30일', '없음'].map(t => {
              const on = expiry === t;
              return (
                <button key={t} onClick={() => setExpiry(t)} className="es-subhead"
                  style={{ flex: 1, padding: '9px 0', borderRadius: 'var(--es-r-sm)', cursor: 'pointer', fontWeight: 600,
                    border: '1px solid ' + (on ? 'var(--es-green)' : 'var(--es-separator-strong)'),
                    background: on ? 'var(--es-green-soft, #E3ECE5)' : 'var(--es-surface)',
                    color: on ? 'var(--es-green-deep, #16281e)' : 'var(--es-ink-2)' }}>{t}</button>
              );
            })}
          </div>
        </div>

        {/* offer summary */}
        <div style={{ padding: '22px 16px 8px' }}>
          <div className="es-list-header">판매 제안 요약</div>
          <div className="es-card" style={{ padding: '4px 16px', boxShadow: 'var(--es-shadow-1)', overflow: 'visible' }}>
            <FieldRow last="first" k="판매 형태" v="지정 판매"
              info="선택한 상대만 수락할 수 있는 판매예요. 마켓에 공개되지 않아요." />
            <FieldRow k="판매 대상" v={picked ? (picked.member ? picked.member.name : shortAddr(picked.addr)) : '미지정'} />
            <FieldRow k="제안 만료" v={expiry} />
            <FieldRow k="수령 예상액" v={`${NET.toLocaleString()} XRP`} mono strong />
          </div>
          <div style={{ display: 'flex', gap: 7, padding: '12px 4px 0', color: 'var(--es-ink-3)' }}>
            <Ic n="info" s={15} style={{ flexShrink: 0, marginTop: 1 }} />
            <span className="es-footnote es-ink-3" style={{ lineHeight: 1.45 }}>
              지정 판매는 대상 지갑만 수락할 수 있어요. 제안 등록에는 소량의 XRPL 예약금(reserve)이 필요하며, 취소 시 되돌려받습니다.
            </span>
          </div>
        </div>
      </Scroll>

      <StickyBar>
        <button className="es-btn es-btn--primary es-btn--block" disabled={!canSubmit}
          onClick={() => canSubmit && setConfirming(true)}
          style={!canSubmit ? { opacity: 0.5 } : undefined}>
          <Ic n="shield-check" s={18} />판매 제안 서명 · 등록
        </button>
      </StickyBar>

      {/* ── iOS 확인 알럿 ── */}
      {confirming && (
      <React.Fragment>
        <style>{'@keyframes esAlertIn{from{transform:scale(1.18);opacity:0}to{transform:scale(1);opacity:1}}@keyframes esDimIn{from{opacity:0}to{opacity:1}}'}</style>
        <div onClick={() => setConfirming(false)} style={{
          position: 'absolute', inset: 0, zIndex: 90, background: 'rgba(0,0,0,0.34)',
          animation: 'esDimIn .2s ease both' }} />
        <div style={{ position: 'absolute', inset: 0, zIndex: 91, display: 'grid', placeItems: 'center', padding: '0 44px',
          animation: 'esAlertIn .26s cubic-bezier(.32,.72,0,1) both' }}>
          <div style={{ width: 270, borderRadius: 14, overflow: 'hidden',
            background: 'rgba(250,250,250,0.82)', backdropFilter: 'saturate(180%) blur(20px)', WebkitBackdropFilter: 'saturate(180%) blur(20px)',
            boxShadow: '0 10px 40px rgba(0,0,0,0.22)' }}>
            <div style={{ padding: '20px 16px 17px', textAlign: 'center' }}>
              <div style={{ fontSize: 17, fontWeight: 600, letterSpacing: '-0.2px', color: '#000' }}>판매 제안을 등록할까요?</div>
              <p style={{ margin: '5px 0 0', fontSize: 13, lineHeight: 1.4, color: 'rgba(0,0,0,0.62)' }}>
                {targetName && <b style={{ color: '#000', fontWeight: 600 }}>{targetName}</b>}님에게 <b style={{ color: '#000', fontWeight: 600 }}>{NET.toLocaleString()} XRP</b> 조건으로 제안을 보냅니다. 등록에는 소량의 예약금(reserve)이 필요해요.
              </p>
            </div>
            <div style={{ display: 'flex', borderTop: '0.5px solid rgba(0,0,0,0.16)' }}>
              <button onClick={() => setConfirming(false)}
                style={{ flex: 1, height: 44, border: 'none', background: 'transparent', color: '#007AFF',
                  cursor: 'pointer', fontFamily: 'inherit', fontSize: 17, fontWeight: 400 }}>취소</button>
              <button onClick={submit}
                style={{ flex: 1, height: 44, border: 'none', borderLeft: '0.5px solid rgba(0,0,0,0.16)',
                  background: 'transparent', color: '#007AFF', fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit', fontSize: 17 }}>등록</button>
            </div>
          </div>
        </div>
      </React.Fragment>
      )}

      {/* ── 검색 시트 (iOS 하프 시트) ── */}
      {searching && (
      <React.Fragment>
        <style>{'@keyframes esSheetUp{from{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes esScrimIn{from{opacity:0}to{opacity:1}}'}</style>
        {/* scrim */}
        <div onClick={() => setSearching(false)} style={{
          position: 'absolute', inset: 0, zIndex: 80, background: 'rgba(18,32,23,0.42)',
          animation: 'esScrimIn .28s ease both' }} />
        {/* sheet */}
        <div style={{
          position: 'absolute', left: 0, right: 0, bottom: 0, zIndex: 81, height: '80%',
          background: 'var(--es-bg)', borderTopLeftRadius: 22, borderTopRightRadius: 22,
          boxShadow: '0 -12px 44px rgba(0,0,0,0.20)', display: 'flex', flexDirection: 'column',
          animation: 'esSheetUp .38s cubic-bezier(.32,.72,0,1) both' }}>
          <div style={{ width: 38, height: 5, borderRadius: 3, background: 'var(--es-fill-press)', margin: '10px auto 4px', flexShrink: 0 }} />

          {/* header + search */}
          <div style={{ padding: '6px 20px 12px', flexShrink: 0 }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
              <div className="es-headline">판매 대상 선택</div>
              <button onClick={() => setSearching(false)} className="es-subhead"
                style={{ border: 'none', background: 'transparent', color: 'var(--es-green)', fontWeight: 600, cursor: 'pointer', padding: 0, fontFamily: 'inherit' }}>
                취소
              </button>
            </div>
            <div className="es-input-group">
              <span className="es-input-icon"><Ic n="search" s={19} /></span>
              <input className="es-input" value={query} autoFocus onChange={e => setQuery(e.target.value)}
                placeholder="이름 또는 지갑 주소(r...)" style={{ fontSize: 15 }} />
            </div>
          </div>

          <div style={{ flex: 1, overflow: 'auto', WebkitOverflowScrolling: 'touch', padding: '0 8px 20px' }}>
            {/* raw wallet address entry */}
            {rawMatch && (
              <button onClick={() => choose({ member: null, addr: q })}
                style={{ width: '100%', display: 'flex', alignItems: 'center', gap: 12, padding: '12px',
                  border: 'none', background: 'transparent', cursor: 'pointer', textAlign: 'left' }}>
                <div style={{ width: 40, height: 40, borderRadius: '50%', background: 'var(--es-surface-2)',
                  color: 'var(--es-bronze)', display: 'grid', placeItems: 'center', flexShrink: 0 }}><Ic n="wallet" s={20} /></div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div className="es-subhead" style={{ fontWeight: 600 }}>이 지갑 주소로 지정</div>
                  <div className="es-caption es-ink-3 es-mono" style={{ marginTop: 1 }}>{shortAddr(q)}</div>
                </div>
              </button>
            )}

            <div className="es-caption es-ink-3" style={{ padding: '10px 12px 6px', fontWeight: 600 }}>
              {q.length >= 1 ? `검색 결과 ${results.length}` : '회원 · 최근 거래 상대'}
            </div>

            {results.map((m) => (
              <button key={m.addr} onClick={() => choose({ member: m, addr: m.addr })}
                style={{ width: '100%', display: 'flex', alignItems: 'center', gap: 12, padding: '10px 12px',
                  border: 'none', borderRadius: 12, background: 'transparent', cursor: 'pointer', textAlign: 'left' }}>
                <Avatar m={m} s={40} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div className="es-subhead" style={{ fontWeight: 600 }}>{m.name}</div>
                  <div className="es-caption es-ink-3 es-mono" style={{ marginTop: 1, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{m.role} · {shortAddr(m.addr)}</div>
                </div>
                <Ic n="chevron-right" s={17} style={{ color: 'var(--es-ink-4)' }} />
              </button>
            ))}

            {q.length >= 1 && results.length === 0 && !rawMatch && (
              <div style={{ padding: '40px 32px', textAlign: 'center' }}>
                <Ic n="search" s={30} style={{ color: 'var(--es-ink-4)' }} />
                <p className="es-subhead es-ink-3" style={{ marginTop: 12, lineHeight: 1.5 }}>
                  '{q}' 검색 결과가 없어요.<br />정확한 이름 또는 지갑 주소(r로 시작)를 입력해 주세요.
                </p>
              </div>
            )}
          </div>
        </div>
      </React.Fragment>
      )}
    </div>
  );
}

// ═════════════════════════════════════════════════════════
//  LICENSING  (라이선싱 발급 · N차 라이선싱)
// ═════════════════════════════════════════════════════════
function LicensingScreen() {
  const [type, setType] = React.useState('전시');
  const [scope, setScope] = React.useState('국내');
  const types = ['전시', '복제', '상업적 사용'];
  const scopes = ['국내', '글로벌'];
  const fee = type === '상업적 사용' ? 480 : type === '복제' ? 260 : 150;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', color: 'var(--es-ink)', background: 'var(--es-bg-grouped)' }}>
      <PushNav title="라이선스 발급" onBack={() => {}} />
      <Scroll>
        <div style={{ padding: '14px 16px 0' }}>
          <div className="es-card es-card--flat" style={{ display: 'flex', alignItems: 'center', gap: 12, padding: 10 }}>
            <Canvas img="assets/dawn-still-life.jpg" h={52} style={{ width: 52, borderRadius: 10, flexShrink: 0 }} />
            <div style={{ flex: 1 }}>
              <div className="es-subhead" style={{ fontWeight: 600 }}>새벽의 정물 No.3</div>
              <div className="es-caption es-ink-3" style={{ marginTop: 1 }}>박서린 · NFT #4821</div>
            </div>
            <span className="es-badge es-badge--info">N차 라이선싱</span>
          </div>
        </div>

        {/* type */}
        <div style={{ padding: '20px 16px 0' }}>
          <div className="es-label" style={{ marginBottom: 10 }}>라이선스 유형</div>
          <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            {types.map(t => (
              <span key={t} className="es-chip" aria-selected={t === type} onClick={() => setType(t)}>{t}</span>
            ))}
          </div>
        </div>

        {/* scope + period */}
        <div style={{ padding: '20px 16px 0' }}>
          <div className="es-label" style={{ marginBottom: 10 }}>사용 범위</div>
          <div className="es-segment">
            {scopes.map(s => (
              <button key={s} className="es-segment__item" aria-selected={s === scope} onClick={() => setScope(s)}>{s}</button>
            ))}
          </div>
        </div>

        <div style={{ padding: '18px 16px 0' }}>
          <div className="es-list">
            <div className="es-row es-row--tappable">
              <div className="es-row__icon" style={{ background: 'var(--es-sage)' }}><Ic n="clock" s={17} /></div>
              <div className="es-row__text"><div className="es-row__title" style={{ fontSize: 16 }}>이용 기간</div></div>
              <span className="es-row__detail" style={{ fontSize: 15 }}>12개월</span>
              <span className="es-row__chev"><Ic n="chevron-right" s={18} /></span>
            </div>
            <div className="es-row es-row--tappable">
              <div className="es-row__icon" style={{ background: 'var(--es-bronze)' }}><Ic n="person" s={17} /></div>
              <div className="es-row__text"><div className="es-row__title" style={{ fontSize: 16 }}>피라이선시</div></div>
              <span className="es-row__detail" style={{ fontSize: 15 }}>갤러리 한도</span>
              <span className="es-row__chev"><Ic n="chevron-right" s={18} /></span>
            </div>
          </div>
        </div>

        {/* revenue split */}
        <div style={{ padding: '20px 16px 8px' }}>
          <div className="es-list-header">수익 분배 (다중서명 정산)</div>
          <div className="es-card" style={{ padding: '4px 16px', boxShadow: 'var(--es-shadow-1)' }}>
            <FieldRow last="first" k="라이선싱 수수료" v={`${fee} XRP`} mono strong />
            <FieldRow k="원작자 (박서린)" v="70%" />
            <FieldRow k="발행처 (EverSeal)" v="20%" />
            <FieldRow k="유통 파트너" v="10%" />
          </div>
          <div style={{ display: 'flex', gap: 7, padding: '12px 4px 0', color: 'var(--es-ink-3)' }}>
            <Ic n="info" s={15} style={{ flexShrink: 0, marginTop: 1 }} />
            <span className="es-footnote es-ink-3" style={{ lineHeight: 1.45 }}>
              라이선스 참조값만 NFT 메타데이터에 기록되고, 기간·범위·분배 정책은 서버에서 관리·정산됩니다.
            </span>
          </div>
        </div>
      </Scroll>

      <StickyBar>
        <button className="es-btn es-btn--gold es-btn--block">라이선스 발급</button>
      </StickyBar>
    </div>
  );
}

// ═════════════════════════════════════════════════════════
//  NFT BURN  (NFT 파기 · EVS-iOS 006)
// ═════════════════════════════════════════════════════════
function BurnScreen() {
  const [agree, setAgree] = React.useState(false);
  const [state, setState] = React.useState('confirm'); // confirm | pending

  if (state === 'pending') {
    return (
      <div style={{ display: 'flex', flexDirection: 'column', height: '100%', color: 'var(--es-ink)', background: 'var(--es-bg-grouped)' }}>
        <PushNav title="NFT 파기" onBack={() => setState('confirm')} />
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '0 28px', textAlign: 'center' }}>
          <div style={{ width: 88, height: 88, borderRadius: '50%', background: 'var(--es-warning-soft)', color: 'var(--es-warning)', display: 'grid', placeItems: 'center', marginBottom: 22 }}>
            <Ic n="clock" s={42} />
          </div>
          <div className="es-title-2">관리자 승인 대기 중</div>
          <p className="es-callout es-ink-2" style={{ marginTop: 10, maxWidth: '30ch', lineHeight: 1.55 }}>
            파기 요청이 접수되었습니다. 관리자 승인 후 NFT가 비활성화되며 거래·인증이 중단됩니다.
          </p>
          <div className="es-card" style={{ width: '100%', marginTop: 24, padding: '4px 16px', boxShadow: 'var(--es-shadow-1)' }}>
            <FieldRow last="first" k="요청 작품" v="새벽의 정물 No.3" />
            <FieldRow k="NFT" v="#4821" mono />
            <FieldRow k="상태" v="승인 대기" />
          </div>
        </div>
        <StickyBar>
          <button className="es-btn es-btn--secondary es-btn--block" onClick={() => setState('confirm')}>대시보드로 돌아가기</button>
        </StickyBar>
      </div>
    );
  }

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', color: 'var(--es-ink)', background: 'var(--es-bg-grouped)' }}>
      <PushNav title="NFT 파기" onBack={() => {}} />
      <Scroll>
        <div style={{ padding: '24px 16px 0', textAlign: 'center' }}>
          <div style={{ width: 76, height: 76, borderRadius: '50%', margin: '0 auto 16px', background: 'var(--es-danger-soft)', color: 'var(--es-danger)', display: 'grid', placeItems: 'center' }}>
            <Ic n="xmark" s={38} sw={2.2} />
          </div>
          <div className="es-title-2">정말 파기하시겠어요?</div>
          <p className="es-callout es-ink-2" style={{ marginTop: 8, lineHeight: 1.55 }}>
            NFT가 비활성화되어 <b>거래·인증이 불가능</b>한 상태로 변경됩니다.
          </p>
        </div>

        <div style={{ padding: '20px 16px 0' }}>
          <div className="es-card es-card--flat" style={{ display: 'flex', alignItems: 'center', gap: 12, padding: 10 }}>
            <Canvas img="assets/dawn-still-life.jpg" h={52} style={{ width: 52, borderRadius: 10, flexShrink: 0 }} />
            <div style={{ flex: 1 }}>
              <div className="es-subhead" style={{ fontWeight: 600 }}>새벽의 정물 No.3</div>
              <div className="es-caption es-ink-3 es-mono" style={{ marginTop: 1 }}>NFT #4821 · ar://0x9f…c2a4</div>
            </div>
          </div>
        </div>

        <div style={{ padding: '18px 16px 0' }}>
          <div style={{ background: 'var(--es-warning-soft)', borderRadius: 'var(--es-r-md)', padding: '12px 14px', display: 'flex', gap: 9 }}>
            <Ic n="info" s={18} style={{ color: 'var(--es-warning)', flexShrink: 0, marginTop: 1 }} />
            <span className="es-footnote" style={{ color: '#8A6320', lineHeight: 1.5 }}>
              파기는 <b>관리자 승인 하에 진행</b>되며, 원장에는 파기 이력이 영구 보존됩니다. 되돌릴 수 없습니다.
            </span>
          </div>
        </div>

        <div style={{ padding: '18px 16px 0' }}>
          <button onClick={() => setAgree(!agree)} style={{ display: 'flex', alignItems: 'center', gap: 12, width: '100%', background: 'none', border: 'none', cursor: 'pointer', textAlign: 'left', padding: 0 }}>
            <span className={'es-check' + (agree ? ' es-check--on' : '')} style={agree ? { background: 'var(--es-danger)', borderColor: 'var(--es-danger)' } : null}>
              {agree && <Ic n="check" s={16} sw={2.6} />}
            </span>
            <span className="es-subhead es-ink-2">위 내용을 확인했으며 되돌릴 수 없음을 이해합니다.</span>
          </button>
        </div>
      </Scroll>

      <StickyBar>
        <button className="es-btn es-btn--block" disabled={!agree} onClick={() => setState('pending')}
          style={{ background: 'var(--es-danger)', color: '#fff' }}>파기 요청</button>
      </StickyBar>
    </div>
  );
}

// ═════════════════════════════════════════════════════════
//  REGISTRATION FORM  (작품 정보 입력 · EVS-iOS 005)
// ═════════════════════════════════════════════════════════
// Toss-style one-step-per-page walkthrough — friendly, plain-language
function RegisterFormScreen({ initialStep = 0 } = {}) {
  const TOTAL = 5;
  const [step, setStep] = React.useState(initialStep);
  const [photo, setPhoto] = React.useState(false);
  // Arweave upload status: 0 none · 1 uploading · 2 done
  const [arUp, setArUp] = React.useState(0);
  React.useEffect(() => {
    if (!photo) { setArUp(0); return; }
    setArUp(1);
    const t = setTimeout(() => setArUp(2), 1600);
    return () => clearTimeout(t);
  }, [photo]);
  const AR_TX = 'ar://0x9f3a7d…c2a4';
  const [sizeW, setSizeW] = React.useState('72.7');
  const [sizeH, setSizeH] = React.useState('60.6');
  const [editionNo, setEditionNo] = React.useState('12');
  const [editionTotal, setEditionTotal] = React.useState('50');
  const [noEdition, setNoEdition] = React.useState(false);
  // XLS-20 권리 범위 — NFTokenMint 의 immutable flags + TransferFee 로열티
  const [royalty, setRoyalty] = React.useState('10');
  const [transferable, setTransferable] = React.useState(true);
  const [onlyXrp, setOnlyXrp] = React.useState(false);
  const [burnable, setBurnable] = React.useState(false);
  // 희망 판매가(KRW) → XRP 환산. 시세는 예시 고정값(1 XRP ≈ ₩3,180)
  const [priceKrw, setPriceKrw] = React.useState('');
  const XRP_KRW = 3180;
  const priceKrwNum = parseFloat(String(priceKrw).replace(/[^\d.]/g, '')) || 0;
  const priceXrp = priceKrwNum > 0 ? priceKrwNum / XRP_KRW : 0;
  const royaltyNum = Math.min(50, Math.max(0, parseFloat(String(royalty).replace(/[^\d.]/g, '')) || 0));
  // TransferFee 는 1/100,000 단위(0.001%) 정수 · 0~50,000 · transferable 이 아니면 설정 불가
  const transferFeeLedger = transferable ? Math.round(royaltyNum * 1000) : 0;
  const next = () => setStep(s => Math.min(TOTAL - 1, s + 1));
  const back = () => setStep(s => Math.max(0, s - 1));
  const pct = ((step + 1) / TOTAL) * 100;
  const isLast = step === TOTAL - 1;

  const Q = ({ children }) => <div className="es-title-1" style={{ letterSpacing: '-0.4px', textWrap: 'pretty' }}>{children}</div>;
  const Help = ({ children }) => <p className="es-callout es-ink-2" style={{ margin: '10px 0 0', lineHeight: 1.5 }}>{children}</p>;

  // read-only key/value row inside a grouped card
  const ReadRow = ({ k, v, mono, first, accent }) => (
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12, padding: '11px 0',
      borderTop: first ? 'none' : '0.5px solid var(--es-separator)' }}>
      <span className="es-subhead es-ink-3" style={{ flexShrink: 0 }}>{k}</span>
      <span className={'es-subhead ' + (mono ? 'es-mono ' : '')} style={{ fontWeight: 600, textAlign: 'right',
        color: accent ? 'var(--es-green)' : 'var(--es-ink)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{v}</span>
    </div>
  );

  // tap-to-choose field (read-as-select; not free text)
  const SIZE_OPTIONS = ['41.0 × 31.8 cm (F6)', '53.0 × 45.5 cm (F10)', '65.2 × 53.0 cm (F15)', '72.7 × 60.6 cm (F20)', '80.3 × 65.2 cm (F25)', '91.0 × 72.7 cm (F30)'];
  const Picker = ({ label, value, onChange, options }) => (
    <div className="es-field">
      <label className="es-label">{label}</label>
      <div style={{ position: 'relative' }}>
        <select className="es-input" value={value} onChange={e => onChange(e.target.value)}
          style={{ appearance: 'none', WebkitAppearance: 'none', paddingRight: 38, cursor: 'pointer' }}>
          {options.map(o => <option key={o} value={o}>{o}</option>)}
        </select>
        <span style={{ position: 'absolute', right: 12, top: '50%', transform: 'translateY(-50%)', pointerEvents: 'none', color: 'var(--es-ink-3)' }}>
          <Ic n="chevron-down" s={18} />
        </span>
      </div>
    </div>
  );

  const ToggleRow = ({ label, sub, on, set, first, disabled }) => (
    <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '13px 0',
      borderTop: first ? 'none' : '0.5px solid var(--es-separator)', opacity: disabled ? 0.45 : 1 }}>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div className="es-subhead" style={{ fontWeight: 600 }}>{label}</div>
        <div className="es-caption es-ink-3" style={{ marginTop: 1 }}>{sub}</div>
      </div>
      <label className="es-switch">
        <input type="checkbox" checked={on} disabled={disabled} onChange={e => set(e.target.checked)} />
        <span className="es-switch__track" />
        <span className="es-switch__thumb" />
      </label>
    </div>
  );

  const body = () => {
    if (step === 0) return (
      <div>
        <div style={{ width: 72, height: 72, borderRadius: '50%', background: 'var(--es-green-soft)', color: 'var(--es-green)', display: 'grid', placeItems: 'center', marginBottom: 18 }}>
          <Ic n="nfc" s={34} />
        </div>
        <Q>작품 태그를 찾았어요</Q>
        <Help>이 태그에 작품 정보를 연결해서 정품으로 등록할게요.</Help>
        <div style={{ marginTop: 22, background: 'var(--es-surface)', borderRadius: 'var(--es-r-md)', padding: '13px 14px', display: 'flex', alignItems: 'center', gap: 11, boxShadow: 'var(--es-shadow-1)' }}>
          <Ic n="qrcode" s={20} style={{ color: 'var(--es-ink-3)' }} />
          <div style={{ flex: 1 }}>
            <div className="es-caption es-ink-3">태그 번호</div>
            <div className="es-subhead es-mono" style={{ fontWeight: 600 }}>04:A2:9F:3C:51:80</div>
          </div>
          <Ic n="check" s={18} style={{ color: 'var(--es-success)' }} sw={2.4} />
        </div>
      </div>
    );
    if (step === 3) return (
      <div>
        <Q>작품 사진을 올려주세요</Q>
        <Help>이 사진이 정품을 확인하는 원본 기록이 돼요. 한 번 올리면 그대로 영구 보관됩니다.</Help>
        <button onClick={() => setPhoto(!photo)} style={{ width: '100%', marginTop: 22, border: 'none', background: 'none', padding: 0, cursor: 'pointer', display: 'block' }}>
          {photo ? (
            <div style={{ position: 'relative', borderRadius: 'var(--es-r-lg)', overflow: 'hidden' }}>
              <Canvas img="assets/dawn-still-life.jpg" h={220} />
              <span className="es-badge es-badge--neutral" style={{ position: 'absolute', bottom: 10, right: 10, background: 'rgba(255,255,255,0.92)' }}>사진 변경</span>
            </div>
          ) : (
            <div style={{ border: '1.5px dashed var(--es-separator-strong)', borderRadius: 'var(--es-r-lg)', padding: '40px 16px', textAlign: 'center', background: 'var(--es-surface)' }}>
              <div style={{ width: 52, height: 52, margin: '0 auto 12px', borderRadius: 14, background: 'var(--es-fill)', color: 'var(--es-ink-3)', display: 'grid', placeItems: 'center' }}>
                <Ic n="plus" s={26} />
              </div>
              <div className="es-subhead" style={{ fontWeight: 600 }}>사진 추가</div>
              <div className="es-caption es-ink-3" style={{ marginTop: 2 }}>탭해서 갤러리에서 선택</div>
            </div>
          )}
        </button>

        {/* before upload: plain-language permanence explainer */}
        {arUp === 0 && (
          <div style={{ marginTop: 16, background: 'var(--es-green-soft)', borderRadius: 'var(--es-r-md)', padding: '14px 15px', display: 'flex', gap: 12, alignItems: 'flex-start' }}>
            <span style={{ color: 'var(--es-green)', flexShrink: 0, marginTop: 1 }}><Ic n="shield-check" s={20} /></span>
            <div>
              <div className="es-subhead" style={{ fontWeight: 600, color: 'var(--es-green-press)' }}>한 번 저장하면 영원히 남아요</div>
              <p className="es-footnote es-ink-2" style={{ margin: '4px 0 0', lineHeight: 1.5 }}>
                사진은 영구 보관 저장소(아위브)에 올라가요. 누구도 수정·삭제할 수 없어 시간이 지나도 원본 그대로 정품을 증명해 줍니다.
              </p>
            </div>
          </div>
        )}

        {/* after upload: Arweave follow-up — read-only record the user can see */}
        {arUp >= 1 && (
          <div className="es-card" style={{ marginTop: 16, padding: '14px 16px 6px', boxShadow: 'var(--es-shadow-1)' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10, paddingBottom: 4 }}>
              <span style={{ width: 30, height: 30, borderRadius: 9, flexShrink: 0, display: 'grid', placeItems: 'center',
                background: arUp === 2 ? 'var(--es-green-soft)' : 'var(--es-fill)', color: 'var(--es-green)' }}>
                <Ic n={arUp === 2 ? 'shield-check' : 'arrow-up-right'} s={17} />
              </span>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div className="es-subhead" style={{ fontWeight: 600 }}>{arUp === 2 ? '영구 저장소에 보관됐어요' : '영구 저장소에 올리는 중…'}</div>
                <div className="es-caption es-ink-3">아위브(Arweave) 영구 보관 네트워크</div>
              </div>
              {arUp === 2
                ? <span className="es-badge es-badge--verified"><Ic n="check" s={11} sw={2.6} />완료</span>
                : <span className="es-badge es-badge--neutral">업로드 중</span>}
            </div>

            {/* progress while uploading */}
            {arUp === 1 && (
              <div style={{ height: 4, borderRadius: 100, background: 'var(--es-separator)', overflow: 'hidden', margin: '8px 0 12px' }}>
                <div style={{ height: '100%', width: '60%', background: 'var(--es-green)', borderRadius: 100, animation: 'esIndet 1.2s ease-in-out infinite' }} />
              </div>
            )}

            {/* read-only metadata */}
            {arUp === 2 && (
              <div style={{ marginTop: 4 }}>
                <ReadRow first k="저장 위치" v="Arweave 영구 보관" accent />
                <ReadRow k="트랜잭션 ID" v={AR_TX} mono />
                <ReadRow k="파일" v="JPEG · 4.2 MB" />
                <ReadRow k="해상도" v="3024 × 4032 px" />
                <ReadRow k="보관 기간" v="영구 · 수정·삭제 불가" />
              </div>
            )}
            <p className="es-caption es-ink-3" style={{ padding: '8px 0 6px', lineHeight: 1.45 }}>
              <Ic n="info" s={13} style={{ verticalAlign: '-2px', marginRight: 4 }} />이 기록은 자동으로 저장되며 수정할 수 없어요.
            </p>
          </div>
        )}
      </div>
    );
    if (step === 1) return (
      <div>
        <Q>작품 정보를 입력해 주세요</Q>
        <Help>구매자에게 보여지고, 정품을 증명하는 기준이 되는 정보예요.</Help>
        <div style={{ marginTop: 22, display: 'flex', flexDirection: 'column', gap: 14 }}>
          <div className="es-field"><label className="es-label">작품명</label><input className="es-input" defaultValue="새벽의 정물 No.3" placeholder="예) 새벽의 정물 No.3" /></div>
          <div style={{ display: 'flex', gap: 12 }}>
            <div className="es-field" style={{ flex: 1 }}><label className="es-label">제작연도</label><input className="es-input" defaultValue="2025" /></div>
            <div className="es-field" style={{ flex: 1 }}>
              <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 6 }}>
                <label className="es-label" style={{ margin: 0 }}>에디션</label>
                <button onClick={() => setNoEdition(v => !v)} style={{ display: 'inline-flex', alignItems: 'center', gap: 5,
                  background: 'none', border: 'none', padding: 0, cursor: 'pointer', fontFamily: 'inherit' }}>
                  <span style={{ width: 16, height: 16, borderRadius: 4, display: 'grid', placeItems: 'center', flexShrink: 0,
                    background: noEdition ? 'var(--es-green)' : 'var(--es-fill)', color: '#fff',
                    border: noEdition ? 'none' : '1px solid var(--es-separator)' }}>
                    {noEdition && <Ic n="check" s={11} sw={3} />}
                  </span>
                  <span className="es-caption es-ink-3">없음</span>
                </button>
              </div>
              {noEdition ? (
                <div className="es-input" style={{ display: 'flex', alignItems: 'center', color: 'var(--es-ink-3)' }}>해당 없음</div>
              ) : (
                <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                  <input className="es-input" style={{ textAlign: 'center' }} type="number" inputMode="numeric" min="1"
                    value={editionNo} onChange={e => setEditionNo(e.target.value)} placeholder="12" />
                  <span className="es-ink-3">/</span>
                  <input className="es-input" style={{ textAlign: 'center' }} type="number" inputMode="numeric" min="1"
                    value={editionTotal} onChange={e => setEditionTotal(e.target.value)} placeholder="50" />
                </div>
              )}
            </div>
          </div>
          <div className="es-field"><label className="es-label">재료 · 기법</label><input className="es-input" defaultValue="캔버스에 유채" /></div>
          <div className="es-field">
            <label className="es-label">작품 크기</label>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <input className="es-input" inputMode="decimal" value={sizeW} onChange={e => setSizeW(e.target.value)} style={{ textAlign: 'center' }} />
              <span className="es-subhead es-ink-3">×</span>
              <input className="es-input" inputMode="decimal" value={sizeH} onChange={e => setSizeH(e.target.value)} style={{ textAlign: 'center' }} />
              <span className="es-subhead es-ink-3" style={{ flexShrink: 0 }}>cm</span>
            </div>
          </div>
        </div>
      </div>
    );
    if (step === 2) return (
      <div>
        <Q>권리 범위를 정해주세요</Q>
        <Help>XRPL 원장(XLS-20)에 새겨지는 권리예요. 발행 후에는 바꿀 수 없으니 신중히 정해주세요.</Help>

        {/* 희망 판매가 (KRW → XRP 자동 환산) */}
        <div style={{ marginTop: 22 }}>
          <div className="es-field">
            <label className="es-label">희망 판매가 <span className="es-ink-3" style={{ fontWeight: 400 }}>· 원(KRW)으로 입력</span></label>
            <div style={{ position: 'relative', display: 'flex', alignItems: 'center' }}>
              <span style={{ position: 'absolute', left: 16, color: 'var(--es-ink-3)', fontWeight: 600, pointerEvents: 'none' }}>₩</span>
              <input className="es-input" value={priceKrw} inputMode="numeric" placeholder="0"
                onChange={e => { const n = e.target.value.replace(/[^\d]/g, ''); setPriceKrw(n ? Number(n).toLocaleString() : ''); }}
                style={{ paddingLeft: 32, fontWeight: 600 }} />
            </div>
          </div>
          {/* live XRP conversion */}
          <div style={{ marginTop: 12, background: 'var(--es-surface)', borderRadius: 'var(--es-r-md)', padding: '12px 14px', boxShadow: 'var(--es-shadow-1)' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 10 }}>
              <span className="es-caption es-ink-3">XRP 환산 금액</span>
              <span className="es-mono" style={{ fontWeight: 700, color: 'var(--es-ink)' }}>
                <span className="es-title-3" style={{ fontWeight: 700 }}>{priceXrp > 0 ? priceXrp.toLocaleString(undefined, { maximumFractionDigits: 2 }) : '—'}</span>
                <span className="es-subhead es-ink-2" style={{ fontWeight: 600, marginLeft: 4 }}>XRP</span>
              </span>
            </div>
            <p className="es-caption es-ink-3" style={{ margin: '6px 0 0', lineHeight: 1.45 }}>
              1 XRP ≈ ₩{XRP_KRW.toLocaleString()} 시세 기준 · 실시간 환율로 자동 계산돼요. 실제 발행가는 등록 시점의 시세로 고정됩니다.
            </p>
          </div>
        </div>

        {/* TransferFee royalty */}
        <div style={{ marginTop: 22 }}>
          <div className="es-field">
            <label className="es-label">2차 판매 로열티 <span className="es-ink-3" style={{ fontWeight: 400 }}>· 발행자 수수료</span></label>
            <div style={{ position: 'relative', display: 'flex', alignItems: 'center', opacity: transferable ? 1 : 0.45 }}>
              <input className="es-input" value={royalty} disabled={!transferable} inputMode="decimal"
                onChange={e => setRoyalty(e.target.value)} style={{ paddingRight: 44, fontWeight: 600 }} />
              <span style={{ position: 'absolute', right: 16, color: 'var(--es-ink-3)', fontWeight: 600, pointerEvents: 'none' }}>%</span>
            </div>
          </div>
          {/* presets */}
          <div style={{ display: 'flex', gap: 8, marginTop: 10 }}>
            {['0', '5', '10', '15', '20'].map(p => {
              const on = transferable && royaltyNum === parseFloat(p);
              return (
                <button key={p} onClick={() => transferable && setRoyalty(p)} disabled={!transferable}
                  className="es-subhead" style={{ flex: 1, padding: '8px 0', borderRadius: 'var(--es-r-sm)', cursor: transferable ? 'pointer' : 'default',
                    fontWeight: 600, border: '1px solid ' + (on ? 'var(--es-green)' : 'var(--es-separator-strong)'),
                    background: on ? 'var(--es-green-soft)' : 'var(--es-surface)', color: on ? 'var(--es-green-press)' : 'var(--es-ink-2)' }}>{p}%</button>
              );
            })}
          </div>
          {/* ledger value explainer (official XLS-20 encoding) */}
          <div style={{ marginTop: 12, background: 'var(--es-surface)', borderRadius: 'var(--es-r-md)', padding: '12px 14px', boxShadow: 'var(--es-shadow-1)' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 10 }}>
              <span className="es-caption es-ink-3">원장 기록값 (TransferFee)</span>
              <span className="es-subhead es-mono" style={{ fontWeight: 700, color: 'var(--es-ink)' }}>{transferFeeLedger.toLocaleString()}</span>
            </div>
            <p className="es-caption es-ink-3" style={{ margin: '6px 0 0', lineHeight: 1.45 }}>
              0~50,000 범위 · 0.001% 단위로 기록돼요. 최대 50%까지 설정할 수 있고, 2차 판매가 일어날 때마다 발행자에게 자동 정산됩니다.
            </p>
          </div>
        </div>

        {/* immutable mint flags */}
        <div className="es-list-header" style={{ marginTop: 22 }}>거래 권한</div>
        <div className="es-card" style={{ padding: '4px 16px', boxShadow: 'var(--es-shadow-1)' }}>
          <ToggleRow first label="재판매 허용" sub="tfTransferable · 다른 소유자에게 양도·판매할 수 있어요" on={transferable}
            set={v => { setTransferable(v); if (!v) setRoyalty('0'); }} />
          <ToggleRow label="XRP로만 거래" sub="tfOnlyXRP · 다른 토큰이 아닌 XRP로만 사고팔 수 있어요" on={onlyXrp} set={setOnlyXrp} />
          <ToggleRow label="발행자 소각 권한" sub="tfBurnable · 발행자가 이 NFT를 파기할 수 있어요" on={burnable} set={setBurnable} />
        </div>

        <div style={{ display: 'flex', gap: 8, padding: '14px 4px 0', color: 'var(--es-ink-3)' }}>
          <Ic n="info" s={15} style={{ flexShrink: 0, marginTop: 1 }} />
          <span className="es-footnote es-ink-3" style={{ lineHeight: 1.45 }}>
            로열티는 재판매가 허용된 경우에만 적용돼요. 이 권리 설정은 발행 시 한 번 새겨지면 영구히 고정됩니다.
          </span>
        </div>
      </div>
    );
    return ( // step 5 — confirm
      <div>
        <Q>이대로 등록할까요?</Q>
        <Help>발행하면 정품 인증서가 만들어지고, 바로 거래할 수 있어요.</Help>
        <div className="es-card es-card--flat" style={{ display: 'flex', gap: 12, padding: 12, marginTop: 22, alignItems: 'center' }}>
          <Canvas img="assets/dawn-still-life.jpg" h={64} style={{ width: 64, borderRadius: 10, flexShrink: 0 }} />
          <div style={{ flex: 1 }}>
            <div className="es-subhead" style={{ fontWeight: 600 }}>새벽의 정물 No.3</div>
            <div className="es-caption es-ink-3" style={{ marginTop: 2 }}>박서린 · 2025 · 캔버스에 유채</div>
            <div className="es-caption es-ink-3" style={{ marginTop: 1 }}>에디션 12 / 50 · {sizeW} × {sizeH} cm</div>
          </div>
        </div>
        <div className="es-card" style={{ padding: '4px 16px', marginTop: 14, boxShadow: 'var(--es-shadow-1)' }}>
          <FieldRow last="first" k="등록 수수료" v="40 XRP" mono strong />
          <FieldRow k="2차 판매 로열티" v={transferable ? royaltyNum.toFixed(3) + '%' : '없음'} mono />
          <FieldRow k="재판매 허용" v={transferable ? '허용' : '불가'} />
          <FieldRow k="영구 보관 (아위브)" v="포함" />
          <FieldRow k="태그 번호" v="04:A2…51:80" mono />
        </div>
        <p className="es-footnote es-ink-3" style={{ marginTop: 12, textAlign: 'center' }}>
          사진과 정보는 아위브에 한 번 저장되면 영구히 보관돼요.
        </p>
      </div>
    );
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', color: 'var(--es-ink)', background: 'var(--es-bg-grouped)' }}>
      <PushNav title="작품 등록" onBack={back}
        right={<span className="es-subhead es-ink-3" style={{ paddingRight: 10 }}>{step + 1}/{TOTAL}</span>} />
      {/* progress */}
      <div style={{ height: 3, background: 'var(--es-separator)', flexShrink: 0 }}>
        <div style={{ height: '100%', width: pct + '%', background: 'var(--es-bronze)', transition: 'width .35s ease' }} />
      </div>
      <Scroll style={{ padding: '26px 20px 0' }}>{body()}</Scroll>
      <StickyBar>
        <button className={'es-btn es-btn--block ' + (isLast ? 'es-btn--gold' : 'es-btn--primary')}
          onClick={isLast ? undefined : next}>
          {isLast ? <><Ic n="seal" s={19} />NFT 발행하기</> : '다음'}
        </button>
      </StickyBar>
    </div>
  );
}

// ═════════════════════════════════════════════════════════
//  REGISTRATION DONE  (등록 완료)
// ═════════════════════════════════════════════════════════
function RegisterDoneScreen() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', color: '#fff', background: 'linear-gradient(180deg,#1a3327 0%,#0f1b14 100%)' }}>
      <div style={{ paddingTop: 50, flexShrink: 0 }} />
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '0 28px', textAlign: 'center' }}>
        <div style={{ width: 96, height: 96, borderRadius: '50%', margin: '0 auto 24px', background: 'var(--es-success)', display: 'grid', placeItems: 'center', color: '#fff', boxShadow: '0 0 60px rgba(42,140,90,0.4)' }}>
          <Ic n="check" s={50} sw={2.4} />
        </div>
        <div className="es-title-1" style={{ color: '#fff' }}>NFT 발행 완료</div>
        <p className="es-callout" style={{ color: 'rgba(255,255,255,0.62)', marginTop: 10, maxWidth: '28ch', lineHeight: 1.55, fontSize: 16 }}>
          작품이 XRPL 원장에 등록되어 정품 인증이 가능해졌습니다.
        </p>

        <div style={{ width: '100%', background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.12)', borderRadius: 'var(--es-r-lg)', padding: '14px 16px', marginTop: 26, textAlign: 'left' }}>
          <div style={{ display: 'flex', gap: 12, alignItems: 'center', marginBottom: 12 }}>
            <Canvas img="assets/dawn-still-life.jpg" h={48} style={{ width: 48, borderRadius: 10, flexShrink: 0 }} />
            <div>
              <div className="es-headline" style={{ color: '#fff' }}>새벽의 정물 No.3</div>
              <div className="es-footnote" style={{ color: 'rgba(255,255,255,0.55)' }}>박서린 · 에디션 12/50</div>
            </div>
          </div>
          {[['NFT 토큰', '#4821'], ['Arweave', 'ar://0x9f…c2a4'], ['발행일', '2026.06.06']].map(([k, v], i) => (
            <div key={i} style={{ display: 'flex', justifyContent: 'space-between', padding: '7px 0', borderTop: '0.5px solid rgba(255,255,255,0.1)' }}>
              <span className="es-subhead" style={{ color: 'rgba(255,255,255,0.6)' }}>{k}</span>
              <span className="es-subhead es-mono" style={{ color: '#fff', fontWeight: 600 }}>{v}</span>
            </div>
          ))}
        </div>
      </div>
      <div style={{ flexShrink: 0, padding: '0 24px 40px', display: 'flex', flexDirection: 'column', gap: 10 }}>
        <button className="es-btn es-btn--gold es-btn--block">작품 보기</button>
        <button className="es-btn es-btn--block" style={{ background: 'rgba(255,255,255,0.12)', color: '#fff' }}>대시보드로</button>
      </div>
    </div>
  );
}

// ═════════════════════════════════════════════════════════
//  VERIFY RESULT  (인증 결과 · 정품 / 위·변조)
// ═════════════════════════════════════════════════════════
function VerifyResultScreen({ result = 'pass' }) {
  const pass = result === 'pass';
  return (
    // sheet presentation: dimmed parent behind + card rising from bottom
    <div style={{ position: 'relative', height: '100%', background: '#05080a' }}>
      {/* dimmed parent (the live scan screen) peeking above the sheet */}
      <div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(120% 80% at 50% 0%, #16241b 0%, #060a07 70%)', opacity: 0.9 }} />

      {/* the sheet */}
      <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, top: 'var(--es-sheet-top, 56px)',
        display: 'flex', flexDirection: 'column', color: '#fff', overflow: 'hidden',
        borderTopLeftRadius: 16, borderTopRightRadius: 16,
        background: pass ? 'linear-gradient(180deg,#1a3327 0%,#0f1b14 100%)' : 'linear-gradient(180deg,#2c2620 0%,#16120d 100%)',
        boxShadow: '0 -12px 40px rgba(0,0,0,0.45)' }}>
        {/* grabber */}
        <div style={{ flexShrink: 0, display: 'flex', justifyContent: 'center', paddingTop: 10, paddingBottom: 4 }}>
          <div style={{ width: 38, height: 5, borderRadius: 100, background: 'rgba(255,255,255,0.32)' }} />
        </div>
        <Scroll>
          <div style={{ padding: '30px 28px 0', textAlign: 'center' }}>
            <div style={{ width: 96, height: 96, borderRadius: '50%', margin: '0 auto 22px',
              background: pass ? 'var(--es-success)' : 'var(--es-warning)', display: 'grid', placeItems: 'center', color: '#fff',
              boxShadow: pass ? '0 0 60px rgba(42,140,90,0.4)' : '0 0 60px rgba(201,150,60,0.32)' }}>
              <Ic n={pass ? 'check' : 'xmark'} s={50} sw={2.4} />
            </div>
            <div className="es-title-1" style={{ color: '#fff' }}>{pass ? '정품이 확인되었습니다' : '정품을 확인할 수 없습니다'}</div>
            {!pass && (
              <p className="es-callout" style={{ color: 'rgba(255,255,255,0.62)', maxWidth: '30ch', margin: '10px auto 0', lineHeight: 1.55 }}>
                태그를 다시 스캔해 주세요.
              </p>
            )}
          </div>

          {pass ? (
            <div style={{ padding: '24px 16px 0' }}>
              <div style={{ background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.12)', borderRadius: 'var(--es-r-lg)', padding: '14px 16px' }}>
                <div style={{ display: 'flex', gap: 12, alignItems: 'center', marginBottom: 12 }}>
                  <Canvas img="assets/dawn-still-life.jpg" h={52} style={{ width: 52, borderRadius: 10, flexShrink: 0 }} />
                  <div>
                    <div className="es-headline" style={{ color: '#fff' }}>새벽의 정물 No.3</div>
                    <div className="es-footnote" style={{ color: 'rgba(255,255,255,0.55)' }}>박서린 · 에디션 12/50</div>
                  </div>
                </div>
                {[['NFC 태그', '정상 · CMAC 검증됨'], ['XRPL NFT', '#4821'], ['토큰 표준', 'XLS-20'], ['발행자', '에버씰'], ['발행일', '2025.03.14'], ['소유자', '박서린'], ['검증 시각', '방금 전']].map(([k, v], i) => (
                  <div key={i} style={{ display: 'flex', justifyContent: 'space-between', padding: '7px 0', borderTop: '0.5px solid rgba(255,255,255,0.1)' }}>
                    <span className="es-subhead" style={{ color: 'rgba(255,255,255,0.6)' }}>{k}</span>
                    <span className="es-subhead" style={{ color: '#fff', fontWeight: 600 }}>{v}</span>
                  </div>
                ))}
              </div>
            </div>
          ) : (
            <div style={{ padding: '24px 16px 0' }}>
              <div style={{ background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.12)', borderRadius: 'var(--es-r-lg)', padding: '14px 16px' }}>
                {[['NFC 인증', '확인되지 않음'], ['NFT 원장 등록', '기록 없음'], ['소유권 대조', '확인 불가']].map(([k, v], i) => (
                  <div key={i} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '8px 0', borderTop: i ? '0.5px solid rgba(255,255,255,0.1)' : 'none' }}>
                    <span className="es-subhead" style={{ color: 'rgba(255,255,255,0.6)' }}>{k}</span>
                    <span className="es-badge" style={{ background: 'rgba(201,150,60,0.18)', color: '#e0b264' }}>{v}</span>
                  </div>
                ))}
              </div>
            </div>
          )}
        </Scroll>

        <div style={{ flexShrink: 0, padding: '14px 24px 36px', display: 'flex', flexDirection: 'column', gap: 10 }}>
          {pass
            ? <button className="es-btn es-btn--gold es-btn--block"><Ic n="eye" s={18} />작품 상세보기</button>
            : <button className="es-btn es-btn--gold es-btn--block"><Ic n="wave" s={18} />다시 스캔</button>}
          <button className="es-btn es-btn--block" style={{ background: 'rgba(255,255,255,0.12)', color: '#fff' }}>닫기</button>
        </div>
      </div>
    </div>
  );
}

// ═════════════════════════════════════════════════════════
//  WALLET — 지갑  (마이페이지 · 계정 > 지갑)
//  EverSeal 플랫폼이 만들어 주는 XRPL 지갑. 최초 생성 → 지갑 정보.
//  최소 구성: ① 지갑 생성 컴포넌트 ② 지갑 정보 ③ 기타 필수
// ═════════════════════════════════════════════════════════
function WalletManageScreen({ initial = 'connected' }) {
  // empty(지갑 없음) | creating | connected(지갑 정보)
  const [state, setState] = React.useState(initial);
  const [addr, setAddr] = React.useState(initial === 'connected' ? 'rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH' : '');
  const shortAddr = addr ? addr.slice(0, 9) + '…' + addr.slice(-5) : '';

  const create = () => {
    setState('creating');
    setTimeout(() => { setAddr('rPv8s2KqWmEx7Yd4LhTnZc9bF6jRnUa3E'); setState('connected'); }, 1600);
  };

  // ── 지갑 생성 컴포넌트 (지갑 없음 / 생성 중) ──────────────
  if (state === 'empty' || state === 'creating') {
    const busy = state === 'creating';
    return (
      <div style={{ display: 'flex', flexDirection: 'column', height: '100%', color: 'var(--es-ink)', background: 'var(--es-bg-grouped)' }}>
        <PushNav title="지갑" onBack={() => {}} />
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', padding: '0 28px' }}>
          <div style={{ position: 'relative', width: 96, height: 96, marginBottom: 26 }}>
            <span style={{ position: 'absolute', inset: 0, borderRadius: '50%', border: '1.5px solid var(--es-gold-border)' }} />
            <span style={{ position: 'absolute', inset: 10, borderRadius: '50%', border: '1px dashed var(--es-gold-border)' }} />
            <span style={{ position: 'absolute', inset: 20, borderRadius: '50%', background: 'var(--es-gold-soft)',
              color: 'var(--es-gold)', display: 'grid', placeItems: 'center' }}>
              {busy
                ? <span style={{ width: 28, height: 28, borderRadius: '50%', border: '3px solid var(--es-gold-soft)',
                    borderTopColor: 'var(--es-gold)', display: 'inline-block', animation: 'esSubSpin 0.8s linear infinite' }} />
                : <Ic n="wallet" s={32} />}
            </span>
          </div>
          <div className="es-title-2" style={{ textWrap: 'balance' }}>{busy ? '지갑을 만들고 있어요' : 'XRPL 지갑 만들기'}</div>
          <p className="es-subhead es-ink-2" style={{ marginTop: 8, lineHeight: 1.55, maxWidth: '30ch' }}>
            {busy
              ? 'XRPL 원장에 안전하게 생성 중…'
              : 'EverSeal가 XRPL 지갑을 만들어 드려요. 작품 등록과 거래에 사용됩니다.'}
          </p>

          {!busy && (
            <div className="es-card es-card--flat" style={{ width: '100%', marginTop: 26, padding: '4px 16px', textAlign: 'left' }}>
              {[
                ['plus', '간편 생성', '복잡한 설정 없이 앱에서 바로'],
                ['lock', '안전한 키 보관', '개인키는 서버에 암호화되어 보관돼요'],
              ].map(([ic, t, s], i) => (
                <div key={t} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '13px 0',
                  borderTop: i ? '0.5px solid var(--es-separator)' : 'none' }}>
                  <div className="es-row__icon" style={{ width: 36, height: 36, background: 'var(--es-gold-soft)', color: 'var(--es-gold)', flexShrink: 0 }}>
                    <Ic n={ic} s={17} />
                  </div>
                  <div>
                    <div className="es-subhead" style={{ fontWeight: 600 }}>{t}</div>
                    <div className="es-caption es-ink-3" style={{ marginTop: 1 }}>{s}</div>
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
        <StickyBar>
          <button className="es-btn es-btn--primary es-btn--block" onClick={create} disabled={busy}>
            {busy ? '생성 중…' : <><Ic n="wallet" s={19} />XRPL 지갑 생성하기</>}
          </button>
        </StickyBar>
      </div>
    );
  }

  // ── 지갑 정보 (지갑 있음) ──────────────────────────────
  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', color: 'var(--es-ink)', background: 'var(--es-bg-grouped)' }}>
      <PushNav title="지갑" onBack={() => {}} />
      <Scroll>
        {/* wallet card */}
        <div style={{ padding: '16px 16px 0' }}>
          <div style={{ borderRadius: 'var(--es-r-xl)', padding: '18px 20px 20px', color: '#fff',
            background: 'linear-gradient(150deg,#16281e 0%,#122017 100%)', position: 'relative', overflow: 'hidden' }}>
            <div style={{ position: 'absolute', right: -34, top: -34, width: 140, height: 140, borderRadius: '50%', background: 'rgba(184,153,122,0.14)' }} />
            <div style={{ display: 'flex', alignItems: 'center', gap: 12, position: 'relative' }}>
              <div className="es-row__icon" style={{ width: 42, height: 42, background: 'rgba(255,255,255,0.12)', color: 'var(--es-bronze-tint)', borderRadius: 12, flexShrink: 0 }}>
                <Ic n="wallet" s={21} />
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div className="es-subhead" style={{ color: '#fff', fontWeight: 600, display: 'flex', alignItems: 'center', gap: 6 }}>
                  EverSeal 지갑
                  <span style={{ fontSize: 10, fontWeight: 700, letterSpacing: '0.4px', color: 'var(--es-bronze-tint)',
                    border: '1px solid rgba(184,153,122,0.5)', borderRadius: 5, padding: '1px 5px' }}>XRPL</span>
                </div>
                <div className="es-caption" style={{ color: 'rgba(255,255,255,0.5)' }}>앱에서 생성 · 서버에 암호화 보관</div>
              </div>
            </div>
            <div style={{ marginTop: 16, paddingTop: 14, borderTop: '0.5px solid rgba(255,255,255,0.12)' }}>
              <div className="es-caption" style={{ color: 'rgba(255,255,255,0.45)' }}>지갑 주소</div>
              <WalletAddrLine addr={addr} />
            </div>
          </div>
        </div>

        {/* 지갑 정보 */}
        <div style={{ padding: '20px 16px 0' }}>
          <div className="es-list-header">지갑 정보</div>
          <div className="es-card" style={{ padding: '4px 16px', boxShadow: 'var(--es-shadow-1)' }}>
            <FieldRow last="first" k="네트워크" v="XRPL Mainnet" />
            <FieldRow k="주소" v={shortAddr} mono />
            <FieldRow k="생성일" v="2025.03.14" />
            <FieldRow k="키 보관" v="서버 암호화 보관" />
          </div>
        </div>

        {/* 기타 필수 */}
        <div style={{ padding: '20px 16px 0' }}>
          <div className="es-list">
            <div className="es-row es-row--tappable">
              <div className="es-row__icon" style={{ background: 'var(--es-ink-2)' }}><Ic n="globe" s={17} /></div>
              <div className="es-row__text"><div className="es-row__title" style={{ fontSize: 16 }}>XRPL 탐색기에서 보기</div></div>
              <span className="es-row__chev"><Ic n="arrow-up-right" s={17} /></span>
            </div>
          </div>
        </div>

        <div style={{ height: 28 }} />
      </Scroll>
    </div>
  );
}

const SUB_SCREENS = {
  detail: AssetDetailScreen,
  trading: TradingScreen,
  licensing: LicensingScreen,
  burn: BurnScreen,
  regform: RegisterFormScreen,
  regdone: RegisterDoneScreen,
  verifypass: () => <VerifyResultScreen result="pass" />,
  verifyfail: () => <VerifyResultScreen result="fail" />,
  wallet: WalletManageScreen,
  walletnew: () => <WalletManageScreen initial="empty" />,
};

Object.assign(window, {
  AssetDetailScreen, TradingScreen, SellOfferScreen, LicensingScreen, BurnScreen,
  RegisterFormScreen, RegisterDoneScreen, VerifyResultScreen, WalletManageScreen, SUB_SCREENS,
});
