/* =========================================================
   Tappt — edit sheet, platform picker, link styles, Pro, share
   ========================================================= */
const {
  PLATFORMS: EP, PLAT_CATS: ECATS, platById: eplat, BrandIcon: EBrand,
  AVATAR_COLORS: EAV, Store: EStore, I: EI, ThemeToggle: EThemeToggle, CARDS: ECARDS,
} = window;
const { useState: eUse, useRef: eRef } = React;

const DEFAULT_SECTIONS = [
  { id: 'bio',      label: 'Bio',            on: true },
  { id: 'featured', label: 'Featured Links', on: true },
  { id: 'embeds',   label: 'Embeds',         on: false },
  { id: 'moments',  label: 'Moments',        on: true },
  { id: 'gallery',  label: 'Gallery',        on: false },
  { id: 'merch',    label: 'Merch & Products', on: false },
  { id: 'exchange', label: 'Exchange',       on: false },
  { id: 'tip',      label: 'Tip jar',        on: false },
];
const LINK_STYLES = [
  { id: 'big',    label: 'Big' },
  { id: 'medium', label: 'Medium' },
  { id: 'small',  label: 'Small' },
  { id: 'button', label: 'Button' },
];
const PROFILE_ANIMS = [
  { id: 'none',    label: 'None',    free: true },
  { id: 'aurora',  label: 'Aurora',  free: false },
  { id: 'shimmer', label: 'Shimmer', free: false },
  { id: 'pulse',   label: 'Pulse',   free: false },
  { id: 'grain',   label: 'Film',    free: false },
  { id: 'glow',    label: 'Glow',    free: false },
  { id: 'float',   label: 'Float',   free: false },
  { id: 'sheen',   label: 'Sheen',   free: false },
];
window.DEFAULT_SECTIONS = DEFAULT_SECTIONS;
window.PROFILE_ANIMS = PROFILE_ANIMS;
window.LINK_STYLES = LINK_STYLES;

/* link animation styles (Pro) — how link cards enter/pulse on the profile */
const LINK_ANIMS = [
  { id: 'none',  label: 'None' },
  { id: 'rise',  label: 'Rise' },
  { id: 'fade',  label: 'Fade' },
  { id: 'pop',   label: 'Pop' },
  { id: 'shimmer', label: 'Shimmer' },
  { id: 'pulse', label: 'Pulse' },
];
/* icon animation styles (Pro) — how the social/app icons move on the profile */
const ICON_ANIMS = [
  { id: 'none',   label: 'None' },
  { id: 'bounce', label: 'Bounce' },
  { id: 'pop',    label: 'Pop' },
  { id: 'wobble', label: 'Wobble' },
  { id: 'float',  label: 'Float' },
  { id: 'spin',   label: 'Spin' },
];
window.ICON_ANIMS = ICON_ANIMS;
/* full profile themes — Light/Dark are FREE (set your public profile's mode independently
   of your own dashboard light/dark toggle); the rest are Pro. */
const PROFILE_THEMES = [
  { id: 'default', label: 'Classic' },
  { id: 'light', label: 'Light', free: true },
  { id: 'midnight', label: 'Midnight' },
  { id: 'glass', label: 'Glass' },
  { id: 'chrome', label: 'Chrome' },
  { id: 'holo', label: 'Holographic' },
  { id: 'paper', label: 'Paper' },
];
window.LINK_ANIMS = LINK_ANIMS;
window.PROFILE_THEMES = PROFILE_THEMES;

/* ===========================================================
   ADD / MANAGE PLATFORM  (overlay above edit sheet)
   =========================================================== */
function AddLinkSheet({ onAdd, onClose, initialStyle, mode }) {
  const social = mode === 'social';
  const [q, setQ] = eUse('');
  const [open, setOpen] = eUse({ Social: true });
  const [style, setStyle] = eUse(initialStyle || 'button');
  const [picked, setPicked] = eUse(null); // platform awaiting handle
  const [handle, setHandle] = eUse('');
  const [media, setMedia] = eUse(null);   // {src, kind:'image'|'video'}

  const matches = (p) => !q || p.label.toLowerCase().includes(q.toLowerCase());
  const byCat = (c) => EP.filter((p) => p.cat === c && matches(p));

  if (picked) {
    const p = eplat(picked);
    return (
      <div className="sheet-bg" onClick={(e) => { if (e.target === e.currentTarget) setPicked(null); }}>
        <div className="sheet">
          <div className="sheet-grab" />
          <div className="sheet-head">
            <button className="glass-pill" style={{ background: 'var(--bg-3)', color: 'var(--fg)', border: '1px solid var(--line)' }} onClick={() => setPicked(null)}>{EI.back({ width: 15, height: 15 })} Back</button>
            <h3>Add {p.label}</h3><span style={{ width: 56 }} />
          </div>
          <div className="sheet-scroll">
            <div style={{ display: 'flex', justifyContent: 'center', margin: '8px 0 18px' }}><EBrand id={p.id} size={72} radius={20} /></div>
            {(() => { const isHandle = (p.ph || '').trim().charAt(0) === '@'; return (
            <div className="field"><label>{p.label} username</label>
              <div className="input-prefix"><span className="pfx">{isHandle ? '@' : (p.base || '—')}</span>
                <input className="input" placeholder={isHandle ? 'username' : p.ph} value={handle} onChange={(e) => setHandle(isHandle ? e.target.value.replace(/^@+/, '') : e.target.value)} /></div></div>
            ); })()}
            {social ? (
              <button className="btn btn-primary btn-block" style={{ marginTop: 4 }} onClick={() => {
                onAdd({ id: Date.now() + Math.random(), type: p.id, label: p.label, url: handle, handle: handle });
              }}>Add to profile</button>
            ) : (
            <React.Fragment>
            <div className="field"><label>Display label</label>
              <input className="input" defaultValue={p.label} id="al-label" /></div>
            <div className="field" style={{ marginBottom: 18 }}><label>Thumbnail (optional)</label>
              <label className="media-drop" style={media ? { padding: 0, border: 'none' } : null}>
                {media
                  ? (media.kind === 'video'
                      ? <video src={media.src} className="media-drop-prev" muted autoPlay loop playsInline />
                      : <img src={media.src} className="media-drop-prev" alt="" />)
                  : <span className="media-drop-empty">{EI.plus({ width: 20, height: 20 })} Add image or video</span>}
                <input type="file" accept="image/*,video/*" style={{ display: 'none' }} onChange={(e) => {
                  const f = e.target.files && e.target.files[0]; if (!f) return;
                  const kind = f.type.startsWith('video') ? 'video' : 'image';
                  const r = new FileReader(); r.onload = () => { setMedia({ src: r.result, kind }); if (style === 'button' || style === 'small') setStyle('big'); }; r.readAsDataURL(f);
                }} />
              </label>
              {media && <button className="btn btn-ghost btn-sm btn-block" style={{ marginTop: 8 }} onClick={() => setMedia(null)}>Remove thumbnail</button>}
              <div className="es-hint" style={{ marginTop: 6 }}>Shown on Big &amp; Medium styles. Auto-cropped to fit.</div>
            </div>
            <div className="field" style={{ marginBottom: 22 }}><label>Style</label>
              <div className="style-grid">
                {LINK_STYLES.map((s) => (
                  <button key={s.id} className={'style-card' + (style === s.id ? ' sel' : '')} onClick={() => setStyle(s.id)}>
                    <span className="style-prev" style={{ background: 'var(--bg-4)', overflow: 'hidden' }}>
                      {(s.id === 'big' || s.id === 'medium') && media
                        ? (media.kind === 'video'
                            ? <video src={media.src} muted style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
                            : <img src={media.src} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />)
                        : <React.Fragment>
                            {s.id === 'big' && <span style={{ width: 34, height: 24, borderRadius: 5, background: p.bg }} />}
                            {s.id === 'medium' && <span style={{ width: 34, height: 14, borderRadius: 4, background: p.bg }} />}
                            {s.id === 'small' && <span style={{ width: 14, height: 14, borderRadius: 4, background: p.bg }} />}
                            {s.id === 'button' && <span style={{ width: 34, height: 11, borderRadius: 999, background: p.bg }} />}
                          </React.Fragment>}
                    </span>
                    <span className="sc-label">{s.label}</span>
                  </button>
                ))}
              </div></div>
            <button className="btn btn-primary btn-block" onClick={() => {
              const label = (document.getElementById('al-label') || {}).value || p.label;
              onAdd({ id: Date.now() + Math.random(), type: p.id, label, url: handle, style, active: true, image: media ? media.src : null, mediaKind: media ? media.kind : null });
            }}>Add to profile</button>
            </React.Fragment>
            )}
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="sheet-bg" onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="sheet">
        <div className="sheet-grab" />
        <div className="sheet-head">
          <button className="glass-pill" style={{ background: 'var(--bg-3)', color: 'var(--fg)', border: '1px solid var(--line)' }} onClick={onClose}>{EI.back({ width: 15, height: 15 })} Done</button>
          <h3>{social ? 'Add app icon' : 'Add a link'}</h3><span style={{ width: 56 }} />
        </div>
        <div className="sheet-scroll">
          <div style={{ fontSize: 13, color: 'var(--fg-3)', margin: '2px 2px 12px' }}>{EP.length} platforms · search or browse</div>
          <div className="search-bar">
            {EI.search ? EI.search({ width: 17, height: 17 }) : '⌕'}
            <input placeholder="Search platforms…" value={q} onChange={(e) => setQ(e.target.value)} />
          </div>
          {ECATS.map((cat) => {
            const list = byCat(cat);
            if (list.length === 0) return null;
            const isOpen = q ? true : !!open[cat];
            return (
              <div className="cat-block" key={cat}>
                <div className="cat-head" onClick={() => setOpen((o) => ({ ...o, [cat]: !o[cat] }))}>
                  <div><div className="ct">{cat}</div><div className="cn">{list.length} platform{list.length > 1 ? 's' : ''}</div></div>
                  <div className={'cat-chev' + (isOpen ? ' open' : '')}>{EI.arrow ? <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4"><path d="M6 9l6 6 6-6"/></svg> : '▾'}</div>
                </div>
                {isOpen && (
                  <div className="plat-row">
                    {list.map((p) => (
                      <button className="plat-pick" key={p.id} onClick={() => { setPicked(p.id); setHandle(''); }}>
                        <EBrand id={p.id} size={48} />
                        <span className="pl">{p.label}</span>
                      </button>
                    ))}
                  </div>
                )}
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

/* ===========================================================
   PRO UPGRADE MODAL
   =========================================================== */
function ProModal({ user, onClose, onUpgrade, onCancel, onRestore, toast }) {
  const isPro = !!user.pro;
  const px = (window.proPricing ? window.proPricing() : { monthly: '£7.99', yearly: '£71.88', yearlyPerMo: '£5.99/mo', save: 'save 25%' });
  const iosIAP = !!(window.isAppleIAP && window.isAppleIAP());
  const [selPlan, setSelPlan] = eUse('yearly');
  const matrix = [
    { t: 'Your Tappt profile & link', free: true, pro: true },
    { t: 'NFC card support', free: true, pro: true },
    { t: 'Multiple profiles & personas', free: false, pro: true },
    { t: 'Animated profiles & themes', free: false, pro: true },
    { t: 'Connection history & map', free: false, pro: true },
    { t: 'Lead capture & auto follow-up', free: false, pro: true },
    { t: 'Advanced analytics', free: false, pro: true },
    { t: 'Custom action buttons', free: false, pro: true },
    { t: 'Priority verified tick', free: false, pro: true },
  ];
  return (
    <div className="sheet-bg" onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="sheet pro-sheet">
        <div className="sheet-grab" />
        <div className="sheet-head" style={{ paddingBottom: 0, marginBottom: 0 }}>
          <span style={{ width: 40 }} />
          <h3 style={{ display: 'flex', alignItems: 'center', gap: 8 }}><span className="pro-badge">PRO</span></h3>
          <button className="icon-btn" onClick={onClose} style={{ width: 36, height: 36 }}>✕</button>
        </div>
        <div className="sheet-scroll">
          <h2 style={{ fontFamily: 'var(--display)', fontWeight: 800, fontSize: 28, letterSpacing: '-0.025em', textAlign: 'center', lineHeight: 1.05, marginBottom: 8, marginTop: 0 }}>
            Make it move.<br />Make it <span style={{ background: 'linear-gradient(135deg,var(--brand),var(--brand-2))', WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent' }}>yours.</span>
          </h2>
          <p style={{ textAlign: 'center', color: 'var(--fg-2)', fontSize: 14, maxWidth: '34ch', margin: '0 auto 22px' }}>
            Everything unlocked — more profiles, motion, and the tools to grow.
          </p>

          <div className="pro-matrix">
            <div className="pm-head">
              <span className="pm-feat"></span>
              <span className="pm-free">Free</span>
              <span className="pm-pro">PRO</span>
            </div>
            {matrix.map((r) => (
              <div className="pm-row" key={r.t}>
                <span className="pm-feat">{r.t}</span>
                <span className={'pm-free' + (r.free ? '' : ' off')}>{r.free ? '✓' : '—'}</span>
                <span className="pm-pro">{r.pro ? <span className="pm-tick">✓</span> : '—'}</span>
              </div>
            ))}
          </div>

          <div style={{ display: 'flex', gap: 10, margin: '20px 0 14px' }}>
            <button onClick={() => setSelPlan('yearly')} className={'pm-plan' + (selPlan === 'yearly' ? ' on' : '')} style={{ flex: 1, border: '1px solid var(--line)', borderRadius: 16, padding: 14, textAlign: 'center', position: 'relative', background: 'transparent', cursor: 'pointer' }}>
              <div style={{ position: 'absolute', top: -9, left: '50%', transform: 'translateX(-50%)', zIndex: 3 }}><span className="pro-badge">Best value</span></div>
              <div style={{ fontFamily: 'var(--display)', fontWeight: 800, fontSize: 22 }}>{px.yearly}<span style={{ fontSize: 13, color: 'var(--fg-3)' }}>/yr</span></div>
              <div style={{ fontSize: 11, color: 'var(--fg-3)' }}>{px.yearlyPerMo} · {px.save}</div>
            </button>
            <button onClick={() => setSelPlan('monthly')} className={'pm-plan' + (selPlan === 'monthly' ? ' on' : '')} style={{ flex: 1, border: '1px solid var(--line)', borderRadius: 16, padding: 14, textAlign: 'center', position: 'relative', background: 'transparent', cursor: 'pointer' }}>
              <div style={{ fontFamily: 'var(--display)', fontWeight: 800, fontSize: 22 }}>{px.monthly}<span style={{ fontSize: 13, color: 'var(--fg-3)' }}>/mo</span></div>
              <div style={{ fontSize: 11, color: 'var(--fg-3)' }}>billed monthly</div>
            </button>
          </div>
          <p style={{ textAlign: 'center', fontSize: 12, color: 'var(--accent)', fontWeight: 700, marginBottom: 14 }}>7 days free · cancel anytime ✦</p>
          <button className="btn btn-primary btn-block pro-cta" onClick={() => { if (isPro) return; onUpgrade(selPlan); }}>{isPro ? 'Pro is active ✓' : 'Start 7-day free trial'}</button>
          {!isPro && <p style={{ textAlign: 'center', fontSize: 11, color: 'var(--fg-3)', marginTop: 10 }}>Cancel anytime · then {selPlan === 'monthly' ? px.monthly + '/mo' : px.yearly + '/yr'}</p>}
          {!isPro && iosIAP && <button className="btn btn-ghost btn-block" style={{ marginTop: 6 }} onClick={() => onRestore && onRestore()}>Restore purchases</button>}
          {isPro && <button className="btn btn-ghost btn-block" style={{ marginTop: 10 }} onClick={() => { onCancel && onCancel(); onClose(); }}>Cancel Pro (demo)</button>}
        </div>
      </div>
    </div>
  );
}

/* ===========================================================
   EDIT PROFILE SHEET
   =========================================================== */
function EditSheet({ user, onClose, onSave, toast, openPro }) {
  const [d, setD] = eUse({
    name: user.name || '', handle: user.handle || '', bio: user.bio || '',
    avatarColor: user.avatarColor || EAV[0],
    cover: user.cover || null,
    email: user.email || '', phone: user.phone || '', saveContact: user.saveContact || false,
    sections: (user.sections && user.sections.length) ? user.sections : DEFAULT_SECTIONS,
    links: user.links || [],
    socials: user.socials || [],
    profileAnim: user.profileAnim || 'none',
    align: user.align || 'centered',
  });
  const set = (p) => setD((s) => ({ ...s, ...p }));
  const [adding, setAdding] = eUse(false);
  const [addStyle, setAddStyle] = eUse(null);
  const [addingSocial, setAddingSocial] = eUse(false);
  const dragIdx = eRef(null);
  const [over, setOver] = eUse(null);
  const isPro = !!user.pro;

  const toggleSection = (id) => set({ sections: d.sections.map((s) => s.id === id ? { ...s, on: !s.on } : s) });
  const onDrop = (i) => {
    const from = dragIdx.current;
    if (from === null || from === i) { setOver(null); return; }
    const next = [...d.sections];
    const [m] = next.splice(from, 1); next.splice(i, 0, m);
    dragIdx.current = null; setOver(null); set({ sections: next });
  };
  const removeLink = (id) => set({ links: d.links.filter((l) => l.id !== id) });
  const toggleSocial = (id) => set({ socials: d.socials.includes(id) ? d.socials.filter((s) => s !== id) : [...d.socials, id] });

  const HINTS = {
    bio: 'A short line under your name.',
    featured: 'Your links, cards and anything front-and-centre.',
    gallery: 'A photo grid to show your world.',
    merch: 'Sell products straight from your profile.',
  };

  return (
    <div className="sheet-bg" onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="sheet">
        <div className="sheet-grab" />
        <div className="sheet-head">
          <button className="glass-pill" style={{ background: 'var(--bg-3)', color: 'var(--fg)', border: '1px solid var(--line)' }} onClick={onClose}>{EI.back({ width: 15, height: 15 })} Cancel</button>
          <h3>Edit Profile</h3>
          <button className="glass-pill" style={{ background: 'var(--accent)', color: 'var(--accent-ink)', border: 'none' }}
            onClick={() => { onSave({ ...d, handle: d.handle.toLowerCase().replace(/[^a-z0-9_.]/g, '') }); toast('Profile saved'); }}>
            {EI.check({ width: 15, height: 15 })} Done
          </button>
        </div>

        <div className="sheet-scroll">
          {/* profile animation (Pro) */}
          <div className="es-block">
            <div className="es-head">
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 14, fontWeight: 700 }}>Profile animation {!isPro && <span className="pro-badge" style={{ marginLeft: 4 }}>PRO</span>}</div>
                <div className="es-hint" style={{ marginTop: 2 }}>Bring your cover to life.</div>
              </div>
            </div>
            <div className="style-grid" style={{ marginTop: 12 }}>
              {PROFILE_ANIMS.map((a) => {
                const locked = !a.free && !isPro;
                return (
                  <button key={a.id} className={'style-card' + (d.profileAnim === a.id ? ' sel' : '')}
                    onClick={() => { if (locked) { openPro(); return; } set({ profileAnim: a.id }); }}>
                    {locked && <span className="pro-lock">🔒</span>}
                    <span className={'style-prev pf-cover-media' + (a.id !== 'none' ? ' anim-' + a.id : '')} style={{ background: d.avatarColor, position: 'relative', overflow: 'hidden' }} />
                    <span className="sc-label">{a.label}</span>
                  </button>
                );
              })}
            </div>
          </div>

          {/* cover photo */}
          <div className="es-block">
            <div className="es-head"><span className="es-title">Cover photo</span></div>
            <div className="es-body">
              <label style={{ display: 'block', borderRadius: 14, overflow: 'hidden', cursor: 'pointer', aspectRatio: '16/9', background: d.avatarColor, position: 'relative' }}>
                {d.cover && <img src={d.cover} alt="" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }} />}
                <span style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontWeight: 700, fontSize: 13, background: 'rgba(0,0,0,0.25)' }}>📷 Change photo or video</span>
                <input type="file" accept="image/*" style={{ display: 'none' }} onChange={(e) => {
                  const f = e.target.files && e.target.files[0]; if (!f) return;
                  const r = new FileReader(); r.onload = () => set({ cover: r.result }); r.readAsDataURL(f);
                }} />
              </label>
            </div>
          </div>

          {/* identity */}
          <div className="es-block">
            <div className="field"><label>Display name</label>
              <input className="input" value={d.name} onChange={(e) => set({ name: e.target.value })} /></div>
            <div className="field"><label>Handle</label>
              <div className="input-prefix"><span className="pfx">tappt.io/</span>
                <input className="input" value={d.handle} onChange={(e) => set({ handle: e.target.value.toLowerCase().replace(/[^a-z0-9_.]/g, '') })} /></div></div>
            <div className="field"><label>Bio line</label>
              <input className="input" value={d.bio} maxLength={90} placeholder="Founder · Tappt · York" onChange={(e) => set({ bio: e.target.value })} /></div>
            <div className="field"><label>Profile layout</label>
              <div className="seg align-seg">
                <button className={d.align === 'centered' ? 'on' : ''} onClick={() => set({ align: 'centered' })}>Centered</button>
                <button className={d.align === 'left' ? 'on' : ''} onClick={() => set({ align: 'left' })}>Left Aligned</button>
              </div></div>
            <div className="field" style={{ marginBottom: 0 }}><label>Profile colour</label>
              <div style={{ display: 'flex', gap: 9 }}>
                {EAV.map((c) => (
                  <button type="button" key={c} onClick={() => set({ avatarColor: c })}
                    style={{ width: 32, height: 32, borderRadius: '50%', background: c, border: d.avatarColor === c ? '2px solid var(--fg)' : '2px solid transparent', boxShadow: d.avatarColor === c ? '0 0 0 2px var(--bg),0 0 0 4px var(--fg)' : 'none' }} />
                ))}
              </div></div>
          </div>

          {/* contact details + save-to-contacts */}
          <div className="es-block">
            <div className="es-head" style={{ marginBottom: 4 }}>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 14, fontWeight: 700 }}>Save to contacts button</div>
                <div className="es-hint" style={{ marginTop: 2 }}>Adds a button that drops your details into their phone.</div>
              </div>
              <button className="switch-wrap" onClick={() => set({ saveContact: !d.saveContact })}><span className={'switch' + (d.saveContact ? ' on' : '')} /></button>
            </div>
            {d.saveContact && (
              <div className="es-body">
                <div className="field"><label>Mobile number</label>
                  <input className="input" type="tel" value={d.phone} placeholder="+44 7…" onChange={(e) => set({ phone: e.target.value })} /></div>
                <div className="field" style={{ marginBottom: 0 }}><label>Email</label>
                  <input className="input" type="email" value={d.email} placeholder="you@mail.com" onChange={(e) => set({ email: e.target.value })} /></div>
              </div>
            )}
          </div>

          {/* social icons */}
          <div className="es-block">
            <div className="es-head"><span className="es-title">Social icons</span>
              <button className="glass-pill" style={{ height: 32, fontSize: 12, background: 'var(--bg-3)', color: 'var(--fg)', border: '1px solid var(--line)' }} onClick={() => setAddingSocial(true)}>+ Add</button></div>
            <div className="plat-row" style={{ marginTop: 12 }}>
              {d.socials.map((s) => (
                <button className="plat-pick" key={s} onClick={() => toggleSocial(s)}>
                  <span style={{ position: 'relative' }}><EBrand id={s} size={46} /><span style={{ position: 'absolute', top: -3, right: -3, width: 18, height: 18, borderRadius: '50%', background: 'var(--danger)', color: '#fff', fontSize: 11, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>−</span></span>
                  <span className="pl">{eplat(s).label}</span>
                </button>
              ))}
            </div>
          </div>

          <div style={{ fontSize: 13, color: 'var(--fg-3)', margin: '4px 4px 10px' }}>Drag to reorder · toggle to show/hide</div>

          {d.sections.map((s, i) => (
            <div key={s.id} className="es-block" draggable
              onDragStart={() => (dragIdx.current = i)}
              onDragOver={(e) => { e.preventDefault(); setOver(i); }}
              onDrop={() => onDrop(i)}
              style={over === i ? { borderColor: 'var(--accent)' } : null}>
              <div className="es-head">
                <span className="grip">{EI.grip({ width: 18, height: 18 })}</span>
                <span className="es-title">{s.label}</span>
                <button className="hide-pill" onClick={() => toggleSection(s.id)}>{s.on ? 'Hide' : 'Show'}</button>
              </div>
              {s.id === 'bio' && s.on && (
                <div className="es-hint">Edit your bio line in the identity card above.</div>
              )}
              {s.id === 'featured' && s.on && (
                <div className="es-body">
                  <div className="link-list">
                    {d.links.map((l) => {
                      const p = eplat(l.type);
                      return (
                        <div className="link-row" key={l.id}>
                          {l.image
                            ? <span className="link-thumb">{l.mediaKind === 'video' ? <video src={l.image} muted /> : <img src={l.image} alt="" />}</span>
                            : <EBrand id={l.type} size={38} radius={10} />}
                          <div className="link-meta"><div className="ln">{l.label || p.label}</div><div className="lu">{l.image ? (l.mediaKind === 'video' ? '🎬 video' : '🖼 image') + ' · ' : ''}{l.style || 'button'}</div></div>
                          <button className="icon-btn danger" onClick={() => removeLink(l.id)}>{EI.trash()}</button>
                        </div>
                      );
                    })}
                  </div>
                  {/* empty placeholder tiles (Lovable-style) */}
                  <div className="add-tiles">
                    <button className="add-tile big" onClick={() => { setAddStyle('big'); setAdding(true); }}>
                      <span className="at-ico">{EI.image ? EI.image({ width: 26, height: 26 }) : '▦'}</span>
                      <span className="at-lbl">+ Add Big Thumbnail Link</span>
                    </button>
                    <div className="add-tiles-row">
                      <button className="add-tile small" onClick={() => { setAddStyle('big'); setAdding(true); }}>
                        <span className="at-ico">{EI.image ? EI.image({ width: 20, height: 20 }) : '▦'}</span>
                        <span className="at-lbl">+ Add Small Thumbnail Link</span>
                      </button>
                      <button className="add-tile small" onClick={() => { setAddStyle('big'); setAdding(true); }}>
                        <span className="at-ico">{EI.image ? EI.image({ width: 20, height: 20 }) : '▦'}</span>
                        <span className="at-lbl">+ Add Small Thumbnail Link</span>
                      </button>
                    </div>
                    <button className="add-tile row" onClick={() => { setAddStyle('button'); setAdding(true); }}>
                      <span className="at-lbl">+ Add No Thumbnail Link</span>
                      <span className="at-ico-sm">{EI.link({ width: 16, height: 16 })}</span>
                    </button>
                    <button className="add-tile row" onClick={() => { setAddStyle('small'); setAdding(true); }}>
                      <span className="at-ico-box">{EI.image ? EI.image({ width: 18, height: 18 }) : '▦'}</span>
                      <span className="at-lbl" style={{ marginLeft: 12 }}>+ Add Multi-Link</span>
                    </button>
                  </div>
                </div>
              )}
              {(!s.on || s.id === 'gallery' || s.id === 'merch') && <div className="es-hint">{HINTS[s.id]}</div>}
            </div>
          ))}

          {/* go pro */}
          {!isPro && (
            <button className="es-block" style={{ width: '100%', textAlign: 'left', background: 'linear-gradient(135deg, rgba(var(--brand-rgb),0.12), rgba(var(--brand2-rgb),0.06))', borderColor: 'rgba(var(--brand-rgb),0.3)' }} onClick={openPro}>
              <div className="es-head"><span className="pro-badge">PRO</span><span className="es-title" style={{ flex: 1, marginLeft: 8 }}>Unlock animations & more</span>{EI.arrow({ width: 18, height: 18 })}</div>
            </button>
          )}
        </div>

        {adding && <AddLinkSheet initialStyle={addStyle} onClose={() => { setAdding(false); setAddStyle(null); }} onAdd={(link) => { set({ links: [...d.links, link] }); setAdding(false); setAddStyle(null); toast('Link added'); }} />}
        {addingSocial && <AddLinkSheet onClose={() => setAddingSocial(false)} onAdd={(link) => { if (!d.socials.includes(link.type)) set({ socials: [...d.socials, link.type] }); setAddingSocial(false); toast('Social added'); }} />}
      </div>
    </div>
  );
}

/* ===========================================================
   TAPPT LINK  (share + linked NFC card sync)
   =========================================================== */
function ShareSheet({ user, onClose, toast, onSave }) {
  const card = ECARDS.find((c) => c.id === user.activeCard);
  const url = `tappt.io/${user.handle || 'you'}`;
  const cardSynced = user.cardSync !== false; // default synced
  return (
    <div className="sheet-bg" onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="sheet">
        <div className="sheet-grab" />
        <div className="sheet-head"><span style={{ width: 36 }} /><h3 style={{ fontSize: 16 }}>Your Tappt Link</h3>
          <button className="icon-btn" onClick={onClose} style={{ width: 36, height: 36 }}>✕</button></div>
        <div className="sheet-scroll" style={{ textAlign: 'center' }}>
          <div className="share-preview">
            <div className="share-float f1" /><div className="share-float f2" /><div className="share-float f3" />
            <div className="share-card-main" style={!card ? { background: user.avatarColor || EAV[0] } : null}>{card && <img src={card.img} alt="" />}</div>
          </div>
          <h2 style={{ fontFamily: 'var(--display)', fontWeight: 800, fontSize: 26, letterSpacing: '-0.02em', lineHeight: 1.05, marginBottom: 10 }}>One link.<br />Everywhere you are.</h2>
          <p style={{ color: 'var(--fg-2)', fontSize: 14, maxWidth: '34ch', margin: '0 auto 22px' }}>Put it in every bio — and it's the same link your Tappt card taps to in person.</p>
          <div className="share-link">
            <span style={{ width: 26, height: 26, borderRadius: 7, background: 'var(--accent)', color: 'var(--accent-ink)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flex: 'none' }}>{EI.link({ width: 14, height: 14 })}</span>
            <span className="lk">{url}</span>
            <button className="cp" onClick={() => { navigator.clipboard && navigator.clipboard.writeText('https://' + url).catch(() => {}); toast('Link copied'); }}>Copy</button>
          </div>

          {/* linked NFC card row */}
          <div className="link-card-row">
            <span className="lc-thumb" style={!card ? { background: user.avatarColor || EAV[0] } : null}>{card && <img src={card.img} alt="" />}</span>
            <div className="lc-meta">
              <div className="lc-t">{card ? card.name + ' card' : 'No card linked'}</div>
              <div className="lc-s">{card ? (cardSynced ? 'Taps open this profile' : 'Uses a separate profile') : 'Order a card to tap in person'}</div>
            </div>
            {card
              ? <button className="switch-wrap" onClick={() => onSave({ cardSync: !cardSynced })}><span className={'switch' + (cardSynced ? ' on' : '')} /></button>
              : <button className="cp" onClick={() => window.open('index.html#shop', '_blank')}>Shop</button>}
          </div>
          {card && <p style={{ fontSize: 12, color: 'var(--fg-3)', margin: '0 0 18px' }}>{cardSynced ? 'Your card and bio link stay in sync automatically.' : 'Manage your card profile separately in Settings.'}</p>}

          <button className="btn btn-primary btn-block" style={{ marginBottom: 10 }} onClick={() => window.open('public.html?u=' + (user.handle || ''), '_blank')}>{EI.ext({ width: 17, height: 17 })} View public profile</button>
          <button className="btn btn-dark btn-block" onClick={() => toast('Opening share…')}>{EI.link({ width: 17, height: 17 })} Share Tappt link</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { EditSheet, ShareSheet, ProModal, AddLinkSheet });
