// future-proof.jsx — Future-Proofing & Strategic Roadmap
// ─────────────────────────────────────────────────────────────────
// Forward-looking signals: emerging tech (AI/blockchain/DDEX),
// regulatory shifts (CMA UK, AI Act, MMA Phonorecords V), business-
// model disruption (direct-to-fan, generative music, NFTs reborn),
// platform risk (DSP exclusivity bans), and a readiness scorecard.
//
// Tabs:
//   01 RADAR        — quadrant: signal × time-horizon
//   02 SIGNALS      — list of forward-looking developments + impact
//   03 SCENARIOS    — three-scenario outlooks (base/bull/bear) for
//                     publisher economics over 5y horizon
//   04 READINESS    — self-assessed scorecard across 12 capabilities
//   05 ROADMAP      — milestone plan with quarter-anchored deliverables
//
// Exports: window.ScreenFutureProof
// ─────────────────────────────────────────────────────────────────
(function () {
  if (typeof window === 'undefined' || !window.React) return;
  const _S = React.useState, _M = React.useMemo;

  function Mono({ children, upper, size, color, style, ...rest }) {
    return <span className={'ff-mono' + (upper?' upper':'')} style={{ fontSize: size||11, color: color||'var(--ink)', letterSpacing: upper?'.08em':0, ...style }} {...rest}>{children}</span>;
  }

  // ─── SIGNALS ──────────────────────────────────────────────────
  const SIGNALS = [
    // EMERGING TECH
    { id:'ai-gen', cat:'AI / GENERATIVE', horizon:'now', impact:5, urgency:5,
      title: 'Generative AI training & licensing',
      desc: 'Training-data licensing (Suno, Udio lawsuits) and AI-generated works create new revenue + dilution simultaneously. Rights-holders must claim training-set inclusion + decide opt-in/out posture.',
      action: 'Adopt training opt-out registry; license catalog to qualified AI partners; tag AI-generated works in metadata (ISWC reform pending).',
      readiness: 'partial' },
    { id:'iswc-v2', cat:'STANDARDS', horizon:'now', impact:4, urgency:4,
      title: 'ISWC reform & granular work IDs',
      desc: 'CISAC ISWC schema being extended for derivatives, AI-generated, fragments, and stems. New ID minting endpoints rolling 2025–26.',
      action: 'Plan migration: map legacy ISWCs to v2 records; enable derivative tracking in catalog model.',
      readiness: 'ready' },
    { id:'ddex-mlc', cat:'STANDARDS', horizon:'now', impact:4, urgency:5,
      title: 'DDEX MLC v4.5 + DSR-F',
      desc: 'DSR-Flat replaces complex hierarchical reporting. MLC v4.5 introduces match-rate transparency and derivative-work fields.',
      action: 'Upgrade conformance suite; build DSR-F ingestion alongside legacy DSR.',
      readiness: 'ready' },
    { id:'cwr-31', cat:'STANDARDS', horizon:'now', impact:3, urgency:4,
      title: 'CWR 3.1 adoption curve',
      desc: 'Major societies (GEMA, PRS, SACEM) on 3.1; mid-tier + emerging on 2.2. Dual-stack required through 2027.',
      action: 'Maintain 2.2/3.0/3.1 generators, society-rule library, fallback strategy.',
      readiness: 'ready' },

    // REGULATION
    { id:'cma-uk', cat:'REGULATION', horizon:'12m', impact:4, urgency:3,
      title: 'CMA UK streaming inquiry remedies',
      desc: 'UK Competition & Markets Authority follow-up on 2023 streaming report — potential remedies on rate transparency, equitable remuneration for performers, and DSP rate-card disclosure.',
      action: 'Prepare disclosure-ready statement formats; track equitable-remuneration policy.',
      readiness: 'partial' },
    { id:'ai-act', cat:'REGULATION', horizon:'12m', impact:5, urgency:5,
      title: 'EU AI Act + transparency obligations',
      desc: 'Article 50 requires disclosure of AI-generated content; Article 53 mandates training-data summaries from foundation-model providers.',
      action: 'Build AI-content metadata flag; implement training-data inclusion claims workflow.',
      readiness: 'partial' },
    { id:'phonorecords-v', cat:'REGULATION', horizon:'24m', impact:5, urgency:3,
      title: 'CRB Phonorecords V (US, 2028–2032)',
      desc: 'Next CRB rate-setting proceeding for US mechanicals; bundles, audio, and video streaming rates re-litigated. Major impact on US 35%-of-global revenue base.',
      action: 'Engage NMPA / DLC counsel; model rate scenarios into forecast engine.',
      readiness: 'gap' },
    { id:'cn-cmo', cat:'REGULATION', horizon:'24m', impact:3, urgency:3,
      title: 'China CMO consolidation',
      desc: 'MCSC/CMRA dispute resolution + onshore-publishing requirements expected to clarify by 2026. Significant upside if transparent regime emerges.',
      action: 'Maintain onshore sub-pub partnership; monitor NCPA/NRTA policy shifts.',
      readiness: 'partial' },

    // BUSINESS MODELS
    { id:'d2f', cat:'BUSINESS MODEL', horizon:'now', impact:4, urgency:3,
      title: 'Direct-to-fan platforms (Bandcamp, Patreon, Substack)',
      desc: 'Higher per-stream economics + first-party fan data + bypass of DSP gatekeepers. Now ~3% of recorded revenue, growing.',
      action: 'Surface D2F revenue alongside DSP in royalty stack; ingest Bandcamp/Patreon statements.',
      readiness: 'gap' },
    { id:'ugc-claim', cat:'BUSINESS MODEL', horizon:'now', impact:5, urgency:5,
      title: 'UGC monetization at scale',
      desc: 'TikTok, YouTube Shorts, Instagram Reels now ~12% of recorded revenue. Content ID claim accuracy directly drives recovery.',
      action: 'Audio-FP module (shipped) + claim queue automation; tier 2 platform integrations.',
      readiness: 'ready' },
    { id:'sync-growth', cat:'BUSINESS MODEL', horizon:'12m', impact:3, urgency:3,
      title: 'Sync market expansion (gaming, FAST channels)',
      desc: 'Gaming sync (Roblox, Fortnite, MetaQuest) + FAST channels growing 18% YoY. Different licensing patterns from film/TV.',
      action: 'Build sync deal templates for gaming/UGC; sync royalty waterfall in claims.',
      readiness: 'partial' },
    { id:'nft-resurgent', cat:'BUSINESS MODEL', horizon:'24m', impact:2, urgency:1,
      title: 'NFT / on-chain royalty rails (post-hype)',
      desc: 'Speculative bubble done; underlying smart-contract royalty splits + provenance tracking maturing. Audius, Sound.xyz, Royal trying again.',
      action: 'Optional: pilot smart-contract split for 1 catalog work to test rails.',
      readiness: 'gap' },

    // PLATFORM RISK
    { id:'dsp-concentration', cat:'PLATFORM RISK', horizon:'12m', impact:4, urgency:3,
      title: 'DSP rate-setting concentration',
      desc: 'Spotify (31% global stream share), Apple, Amazon set effective rates. Tencent/NetEase exclusivity ban (2021) precedent for antitrust action.',
      action: 'Diversify DSP exposure; track Spotify policy changes (bundle accounting, "discovery mode" payola).',
      readiness: 'partial' },
    { id:'spotify-bundle', cat:'PLATFORM RISK', horizon:'now', impact:4, urgency:5,
      title: 'Spotify "bundle" mechanical discount',
      desc: '2024 reclassification of premium as "bundle with audiobooks" cuts mechanical rate ~15%. NMPA litigating.',
      action: 'Model recoverable shortfall; track NMPA case outcome; flag affected statements.',
      readiness: 'ready' },

    // INFRASTRUCTURE
    { id:'realtime-payments', cat:'INFRASTRUCTURE', horizon:'24m', impact:3, urgency:2,
      title: 'Real-time / weekly royalty distribution',
      desc: 'CMOs piloting weekly distribution (PRS, SOCAN). Cash-flow shift for songwriters; reconciliation cadence accelerates.',
      action: 'Reconciliation engine to handle weekly ingestion; cash-flow projection refresh.',
      readiness: 'partial' },
    { id:'open-data', cat:'INFRASTRUCTURE', horizon:'24m', impact:3, urgency:2,
      title: 'Open registries (MLC public data, ISNI, Wikidata)',
      desc: 'Industry open-data movement makes match enrichment cheaper; ISNI now 17M IDs; Wikidata bridging well.',
      action: 'Wire match-engine to open registries; reduce reliance on paywalled lookup.',
      readiness: 'ready' },
  ];

  const HORIZON = {
    'now':  { l: 'NOW · 0–6mo',   c: '#a32a18', x: 0 },
    '12m':  { l: '12mo',          c: '#d4881f', x: 1 },
    '24m':  { l: '24mo+',         c: '#1a4ed8', x: 2 },
  };
  const READINESS = {
    'ready':   { l: 'READY',   c: '#0a8754' },
    'partial': { l: 'PARTIAL', c: '#d4881f' },
    'gap':     { l: 'GAP',     c: '#a32a18' },
  };
  const CATS = [...new Set(SIGNALS.map(s => s.cat))];

  // ─── 01 RADAR ────────────────────────────────────────────────
  function RadarTab() {
    // Quadrant: x = horizon (now → 24m), y = impact (1–5)
    const W = 720, H = 440, PAD = 60;
    const xFor = (h) => PAD + (HORIZON[h].x / 2) * (W - PAD * 2);
    const yFor = (impact) => H - PAD - ((impact - 1) / 4) * (H - PAD * 2);

    return (
      <div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', borderTop: '1px solid var(--rule)', borderBottom: '1px solid var(--rule)', marginBottom: 24 }}>
          <Cell label="SIGNALS TRACKED" value={SIGNALS.length} sub="across 6 categories"/>
          <Cell label="HIGH IMPACT" value={SIGNALS.filter(s => s.impact >= 4).length} sub="impact ≥ 4 of 5" tone="#a32a18"/>
          <Cell label="URGENT (NOW)" value={SIGNALS.filter(s => s.horizon === 'now').length} sub="0–6 month horizon" tone="#d4881f"/>
          <Cell label="READY" value={SIGNALS.filter(s => s.readiness === 'ready').length} sub={'/ ' + SIGNALS.length + ' fully prepared'} tone="#0a8754"/>
        </div>

        <div style={{ border: '1px solid var(--rule)', padding: 18, marginBottom: 18, background: 'var(--paper)' }}>
          <Mono upper size={9} color="var(--ink-3)" style={{ marginBottom: 6, display: 'block' }}>HORIZON × IMPACT QUADRANT</Mono>
          <svg viewBox={`0 0 ${W} ${H}`} style={{ width: '100%', height: 'auto', display: 'block' }}>
            {/* axes */}
            <line x1={PAD} y1={H-PAD} x2={W-PAD} y2={H-PAD} stroke="var(--ink-3)" strokeWidth="1"/>
            <line x1={PAD} y1={PAD} x2={PAD} y2={H-PAD} stroke="var(--ink-3)" strokeWidth="1"/>
            {/* x ticks */}
            {Object.entries(HORIZON).map(([k, v]) => (
              <g key={k}>
                <line x1={xFor(k)} y1={H-PAD} x2={xFor(k)} y2={H-PAD+5} stroke="var(--ink-3)"/>
                <text x={xFor(k)} y={H-PAD+22} fontSize="10" textAnchor="middle" fill="var(--ink-2)" fontFamily="ui-monospace, monospace" letterSpacing="0.06em">{v.l}</text>
              </g>
            ))}
            {/* y labels */}
            {[1,2,3,4,5].map(i => (
              <g key={i}>
                <line x1={PAD-5} y1={yFor(i)} x2={PAD} y2={yFor(i)} stroke="var(--ink-3)"/>
                <text x={PAD-10} y={yFor(i)+3} fontSize="10" textAnchor="end" fill="var(--ink-2)" fontFamily="ui-monospace, monospace">{i}</text>
              </g>
            ))}
            {/* quadrant labels */}
            <text x={PAD} y={PAD-12} fontSize="9" fill="var(--ink-3)" fontFamily="ui-monospace, monospace" letterSpacing="0.08em">IMPACT ↑</text>
            <text x={W-PAD} y={H-PAD+38} fontSize="9" fill="var(--ink-3)" textAnchor="end" fontFamily="ui-monospace, monospace" letterSpacing="0.08em">HORIZON →</text>
            {/* dots */}
            {SIGNALS.map((s, i) => {
              // jitter: same-cell dots offset
              const sameSpot = SIGNALS.filter(o => o.horizon === s.horizon && o.impact === s.impact);
              const idx = sameSpot.indexOf(s);
              const offsetX = (idx - (sameSpot.length - 1) / 2) * 22;
              const cx = xFor(s.horizon) + offsetX;
              const cy = yFor(s.impact);
              const r = 5 + s.urgency * 1.2;
              return (
                <g key={s.id}>
                  <circle cx={cx} cy={cy} r={r} fill={READINESS[s.readiness].c} fillOpacity="0.8" stroke="var(--bg)" strokeWidth="1.5"/>
                  <text x={cx} y={cy + r + 11} fontSize="8.5" textAnchor="middle" fill="var(--ink-2)" fontFamily="ui-monospace, monospace">{s.id}</text>
                </g>
              );
            })}
          </svg>
          <div style={{ display: 'flex', gap: 18, marginTop: 14, flexWrap: 'wrap' }}>
            {Object.entries(READINESS).map(([k, v]) => (
              <span key={k} style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
                <span style={{ width: 10, height: 10, background: v.c, borderRadius: '50%' }}/>
                <Mono upper size={9} color="var(--ink-2)">{v.l}</Mono>
              </span>
            ))}
            <Mono size={10} color="var(--ink-3)" style={{ marginLeft: 'auto' }}>dot size = urgency · y-axis = impact (1–5) · x-axis = horizon</Mono>
          </div>
        </div>
      </div>
    );
  }

  // ─── 02 SIGNALS ──────────────────────────────────────────────
  function SignalsTab() {
    const [catFilter, setCatFilter] = _S('all');
    const [readyFilter, setReadyFilter] = _S('all');
    const visible = SIGNALS.filter(s =>
      (catFilter === 'all' || s.cat === catFilter) &&
      (readyFilter === 'all' || s.readiness === readyFilter)
    ).sort((a, b) => b.impact * b.urgency - a.impact * a.urgency);

    return (
      <div>
        <div style={{ display: 'flex', gap: 6, marginBottom: 14, flexWrap: 'wrap' }}>
          {[{ k: 'all', l: 'All' }, ...CATS.map(c => ({ k: c, l: c }))].map(f => (
            <button key={f.k} onClick={() => setCatFilter(f.k)} className="ff-mono upper" style={{
              fontSize: 9, padding: '5px 9px',
              background: catFilter === f.k ? 'var(--ink)' : 'transparent',
              color: catFilter === f.k ? '#fff' : 'var(--ink-2)',
              border: '1px solid ' + (catFilter === f.k ? 'var(--ink)' : 'var(--rule)'), cursor: 'pointer',
            }}>{f.l}</button>
          ))}
          <span style={{ width: 1, background: 'var(--rule)', margin: '0 6px' }}/>
          {[{ k: 'all', l: 'Any readiness' }, ...Object.entries(READINESS).map(([k, v]) => ({ k, l: v.l }))].map(f => (
            <button key={f.k} onClick={() => setReadyFilter(f.k)} className="ff-mono upper" style={{
              fontSize: 9, padding: '5px 9px',
              background: readyFilter === f.k ? 'var(--ink)' : 'transparent',
              color: readyFilter === f.k ? '#fff' : 'var(--ink-2)',
              border: '1px solid ' + (readyFilter === f.k ? 'var(--ink)' : 'var(--rule)'), cursor: 'pointer',
            }}>{f.l}</button>
          ))}
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          {visible.map(s => {
            const r = READINESS[s.readiness], h = HORIZON[s.horizon];
            return (
              <div key={s.id} style={{ border: '1px solid var(--rule)', borderLeft: '3px solid ' + r.c, padding: '14px 18px', background: 'var(--paper)' }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 14, marginBottom: 8 }}>
                  <div style={{ flex: 1 }}>
                    <div style={{ display: 'flex', gap: 8, alignItems: 'center', marginBottom: 4, flexWrap: 'wrap' }}>
                      <Mono upper size={9} color="var(--ink-3)">{s.cat}</Mono>
                      <Mono size={9} style={{ background: h.c, color: '#fff', padding: '2px 5px', letterSpacing: '0.08em' }}>{h.l}</Mono>
                      <Mono size={9} style={{ background: r.c, color: '#fff', padding: '2px 5px', letterSpacing: '0.08em' }}>{r.l}</Mono>
                    </div>
                    <div style={{ fontSize: 15, fontWeight: 600 }}>{s.title}</div>
                  </div>
                  <div style={{ display: 'flex', gap: 12, fontSize: 10, color: 'var(--ink-3)', textAlign: 'right' }}>
                    <div>
                      <Mono upper size={8}>IMPACT</Mono>
                      <div className="ff-display" style={{ fontSize: 18, fontWeight: 600 }}>{s.impact}</div>
                    </div>
                    <div>
                      <Mono upper size={8}>URGENCY</Mono>
                      <div className="ff-display" style={{ fontSize: 18, fontWeight: 600 }}>{s.urgency}</div>
                    </div>
                  </div>
                </div>
                <div style={{ fontSize: 12.5, color: 'var(--ink-2)', lineHeight: 1.55, marginBottom: 10 }}>{s.desc}</div>
                <div style={{ borderTop: '1px solid var(--rule-soft)', paddingTop: 8 }}>
                  <Mono upper size={9} color="var(--ink-3)">RECOMMENDED ACTION</Mono>
                  <div style={{ fontSize: 12, marginTop: 4, lineHeight: 1.5 }}>{s.action}</div>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    );
  }

  // ─── 03 SCENARIOS ────────────────────────────────────────────
  const SCENARIOS = [
    {
      k: 'base', l: 'BASE CASE', c: '#1a4ed8', prob: 55,
      headline: 'Status quo accelerates',
      cagr: 8.4,
      pillars: [
        'Streaming continues 8–10% YoY · UGC rises to 18% of recorded',
        'AI training settled via licensing (post-Suno/Udio); collective bargaining via NMPA/RIAA',
        'CWR 3.1 universal by 2027 · DSR-Flat replaces legacy by 2026',
        'CMA/EU AI Act drives moderate transparency gains; no major rate restructuring',
        'Tier-1 publishers consolidate; mid-tier squeezed on tech leverage',
      ],
    },
    {
      k: 'bull', l: 'BULL CASE', c: '#0a8754', prob: 25,
      headline: 'Rights infrastructure modernizes',
      cagr: 12.6,
      pillars: [
        'Phonorecords V awards meaningful rate increases (2028)',
        'AI training compulsory licensing standardized (US + EU); injects 4–6% recurring',
        'Real-time distribution becomes industry default; cash-flow advantages compound',
        'Open registries (MLC, ISNI, Wikidata) reduce match cost 40%+',
        'Emerging markets (NG, IN, BR) CMO transparency improves; collection rates rise from ~60% to ~80%',
      ],
    },
    {
      k: 'bear', l: 'BEAR CASE', c: '#a32a18', prob: 20,
      headline: 'Disruption outpaces adaptation',
      cagr: 2.1,
      pillars: [
        'Generative-AI dilutes catalog (uncompensated training); per-stream rate falls',
        'DSP bundle accounting expands beyond Spotify; mechanical rate erodes 20%',
        'CWR 3.1 / DDEX adoption stalls; dual-stack costs compound',
        'CN/RU/MENA regulatory walls fragment global revenue',
        'Direct-to-fan platforms cannibalize DSP revenue without offsetting per-fan',
      ],
    },
  ];

  function ScenariosTab() {
    return (
      <div>
        <div style={{ padding: '14px 18px', background: 'var(--bg-2)', border: '1px solid var(--rule)', marginBottom: 22 }}>
          <Mono upper size={9} color="var(--ink-3)" style={{ marginBottom: 4, display: 'block' }}>5-YEAR PUBLISHING ECONOMICS · 2025–2030</Mono>
          <div style={{ fontSize: 12, color: 'var(--ink-2)', lineHeight: 1.5 }}>
            Three-scenario outlook across catalog earnings, infrastructure cost, and regulatory exposure. Probabilities are subjective management estimates; CAGR is on net publisher share.
          </div>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 14 }}>
          {SCENARIOS.map(s => (
            <div key={s.k} style={{ border: '1px solid var(--rule)', borderTop: '4px solid ' + s.c, padding: '20px 22px', background: 'var(--paper)' }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 14 }}>
                <Mono upper size={10} style={{ color: s.c, fontWeight: 600 }}>{s.l}</Mono>
                <Mono upper size={9} color="var(--ink-3)">{s.prob}% PROB</Mono>
              </div>
              <div style={{ fontSize: 16, fontWeight: 600, marginBottom: 10, lineHeight: 1.3 }}>{s.headline}</div>
              <div style={{ borderTop: '1px solid var(--rule)', borderBottom: '1px solid var(--rule)', padding: '12px 0', margin: '14px 0' }}>
                <Mono upper size={9} color="var(--ink-3)">5Y CAGR · NET PUBLISHER SHARE</Mono>
                <div className="ff-display" style={{ fontSize: 32, fontWeight: 600, letterSpacing: '-0.02em', color: s.c, marginTop: 4 }}>
                  {s.cagr > 0 ? '+' : ''}{s.cagr}%
                </div>
              </div>
              <ul style={{ paddingLeft: 16, margin: 0, fontSize: 12, lineHeight: 1.6, color: 'var(--ink-2)' }}>
                {s.pillars.map((p, i) => <li key={i} style={{ marginBottom: 6 }}>{p}</li>)}
              </ul>
            </div>
          ))}
        </div>

        {/* Aggregated chart */}
        <div style={{ border: '1px solid var(--rule)', padding: 18, marginTop: 22, background: 'var(--paper)' }}>
          <Mono upper size={9} color="var(--ink-3)" style={{ marginBottom: 10, display: 'block' }}>PROJECTED NET INDEX · 2025 = 100</Mono>
          <svg viewBox="0 0 720 240" style={{ width: '100%', height: 240, display: 'block' }}>
            {/* gridlines */}
            {[0, 1, 2, 3, 4].map(i => (
              <g key={i}>
                <line x1={50} y1={20 + i * 50} x2={700} y2={20 + i * 50} stroke="var(--rule-soft)" strokeWidth="1"/>
                <text x={45} y={24 + i * 50} fontSize="10" textAnchor="end" fill="var(--ink-3)" fontFamily="ui-monospace, monospace">{200 - i * 25}</text>
              </g>
            ))}
            {/* x labels */}
            {[2025, 2026, 2027, 2028, 2029, 2030].map((y, i) => (
              <text key={y} x={50 + (i / 5) * 650} y={236} fontSize="10" fill="var(--ink-3)" textAnchor="middle" fontFamily="ui-monospace, monospace">{y}</text>
            ))}
            {/* lines */}
            {SCENARIOS.map(s => {
              const pts = [];
              for (let yr = 0; yr <= 5; yr++) {
                const x = 50 + (yr / 5) * 650;
                const v = 100 * Math.pow(1 + s.cagr / 100, yr);
                const y = 220 - ((v - 100) / 100) * 200;
                pts.push(x + ',' + y);
              }
              return (
                <g key={s.k}>
                  <polyline points={pts.join(' ')} fill="none" stroke={s.c} strokeWidth="2.5"/>
                  {pts.map((p, i) => {
                    const [x, y] = p.split(',').map(Number);
                    return <circle key={i} cx={x} cy={y} r="3" fill={s.c}/>;
                  })}
                  <text x={pts[pts.length - 1].split(',')[0] - 4} y={Number(pts[pts.length - 1].split(',')[1]) - 8} fontSize="11" fill={s.c} textAnchor="end" fontWeight="600" fontFamily="ui-monospace, monospace">{s.l.replace(' CASE', '')}</text>
                </g>
              );
            })}
          </svg>
        </div>
      </div>
    );
  }

  // ─── 04 READINESS ────────────────────────────────────────────
  const CAPABILITIES = [
    { k: 'cwr',         l: 'CWR 2.2/3.0/3.1 dual-stack', score: 92, target: 95, owner: 'Platform' },
    { k: 'ddex',        l: 'DDEX DSR-Flat ingestion',     score: 70, target: 90, owner: 'Platform' },
    { k: 'mlc',         l: 'MLC v4.5 match accuracy',     score: 88, target: 95, owner: 'Match' },
    { k: 'fp',          l: 'Audio fingerprinting',        score: 80, target: 90, owner: 'Detection' },
    { k: 'ugc',         l: 'UGC claim automation',        score: 75, target: 90, owner: 'Detection' },
    { k: 'ai-tag',      l: 'AI-generated content metadata',score: 30, target: 80, owner: 'Standards' },
    { k: 'ai-license',  l: 'AI training opt-out + license',score: 45, target: 85, owner: 'Legal' },
    { k: 'd2f',         l: 'D2F revenue ingestion',       score: 25, target: 70, owner: 'Royalties' },
    { k: 'realtime',    l: 'Real-time / weekly distrib.', score: 60, target: 85, owner: 'Royalties' },
    { k: 'open-data',   l: 'Open registries (ISNI, MLC)', score: 78, target: 90, owner: 'Match' },
    { k: 'sync-game',   l: 'Gaming sync workflow',        score: 35, target: 75, owner: 'Licensing' },
    { k: 'cn-onshore',  l: 'China onshore sub-pub',       score: 55, target: 75, owner: 'Markets' },
  ];

  function ReadinessTab() {
    const overall = Math.round(CAPABILITIES.reduce((s, c) => s + c.score, 0) / CAPABILITIES.length);
    const targetAvg = Math.round(CAPABILITIES.reduce((s, c) => s + c.target, 0) / CAPABILITIES.length);
    const gap = targetAvg - overall;

    return (
      <div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', borderTop: '1px solid var(--rule)', borderBottom: '1px solid var(--rule)', marginBottom: 22 }}>
          <Cell label="OVERALL READINESS" value={overall + '%'} sub={'across ' + CAPABILITIES.length + ' capabilities'} tone={overall >= 75 ? '#0a8754' : overall >= 60 ? '#d4881f' : '#a32a18'}/>
          <Cell label="TARGET STATE" value={targetAvg + '%'} sub="weighted avg target"/>
          <Cell label="GAP TO CLOSE" value={gap + 'pp'} sub="aggregate execution debt" tone="#a32a18"/>
          <Cell label="CAPS BELOW 50%" value={CAPABILITIES.filter(c => c.score < 50).length} sub="critical attention" tone={CAPABILITIES.filter(c => c.score < 50).length > 0 ? '#a32a18' : undefined}/>
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {CAPABILITIES.sort((a, b) => (a.score - a.target) - (b.score - b.target)).map(c => {
            const tone = c.score >= 80 ? '#0a8754' : c.score >= 60 ? '#d4881f' : '#a32a18';
            return (
              <div key={c.k} style={{ display: 'grid', gridTemplateColumns: '1fr 80px 1fr 60px 90px', gap: 14, padding: '12px 16px', border: '1px solid var(--rule)', alignItems: 'center', background: 'var(--paper)' }}>
                <div>
                  <div style={{ fontSize: 13, fontWeight: 500 }}>{c.l}</div>
                  <Mono upper size={9} color="var(--ink-3)" style={{ marginTop: 2 }}>{c.owner}</Mono>
                </div>
                <Mono size={11} color="var(--ink-2)">target {c.target}%</Mono>
                <div style={{ position: 'relative', height: 8, background: 'var(--bg-2)' }}>
                  <div style={{ position: 'absolute', left: 0, top: 0, height: '100%', width: c.score + '%', background: tone }}/>
                  <div style={{ position: 'absolute', left: c.target + '%', top: -2, width: 1, height: 12, background: 'var(--ink)' }}/>
                </div>
                <Mono size={14} style={{ textAlign: 'right', fontWeight: 600, color: tone }}>{c.score}%</Mono>
                <Mono size={11} style={{ textAlign: 'right', color: c.score < c.target ? '#a32a18' : '#0a8754' }}>{c.score < c.target ? '−' : '+'}{Math.abs(c.target - c.score)}pp</Mono>
              </div>
            );
          })}
        </div>
      </div>
    );
  }

  // ─── 05 ROADMAP ──────────────────────────────────────────────
  const MILESTONES = [
    { q: 'Q1 2025', items: [
      { l: 'CWR 3.1 society rule pack expansion (+ KOMCA, MCSC, IPRS)', tag: 'Standards', done: true },
      { l: 'AI-generated metadata flag in catalog model', tag: 'AI', done: true },
      { l: 'UGC claim queue automation (Audio FP shipped)', tag: 'Detection', done: true },
    ]},
    { q: 'Q2 2025', items: [
      { l: 'DDEX DSR-Flat ingestion pipeline alongside legacy DSR', tag: 'Standards', done: false },
      { l: 'AI training opt-out registry integration', tag: 'AI', done: false },
      { l: 'D2F revenue ingestion (Bandcamp, Patreon)', tag: 'Royalties', done: false },
    ]},
    { q: 'Q3 2025', items: [
      { l: 'Real-time distribution support (PRS weekly pilot)', tag: 'Royalties', done: false },
      { l: 'Gaming sync workflow templates (Roblox, Fortnite)', tag: 'Licensing', done: false },
      { l: 'Spotify bundle shortfall reconciliation tooling', tag: 'Royalties', done: false },
    ]},
    { q: 'Q4 2025', items: [
      { l: 'CMA UK transparency disclosure formats', tag: 'Regulation', done: false },
      { l: 'EU AI Act Art.50/53 compliance toolkit', tag: 'Regulation', done: false },
      { l: 'Open-registry match-engine v2 (ISNI + Wikidata)', tag: 'Match', done: false },
    ]},
    { q: '2026', items: [
      { l: 'ISWC v2 migration · derivative tracking', tag: 'Standards', done: false },
      { l: 'CN onshore sub-pub flow + monitoring', tag: 'Markets', done: false },
      { l: 'Phonorecords V scenario-modeling integration', tag: 'Forecast', done: false },
    ]},
  ];

  function RoadmapTab() {
    const total = MILESTONES.reduce((s, m) => s + m.items.length, 0);
    const done = MILESTONES.reduce((s, m) => s + m.items.filter(i => i.done).length, 0);
    return (
      <div>
        <div style={{ padding: '14px 18px', background: 'var(--bg-2)', border: '1px solid var(--rule)', marginBottom: 22, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <div>
            <Mono upper size={9} color="var(--ink-3)" style={{ marginBottom: 4, display: 'block' }}>FUTURE-PROOFING ROADMAP · 2025–2026</Mono>
            <div style={{ fontSize: 12, color: 'var(--ink-2)' }}>{done} of {total} milestones shipped · execution rate {Math.round(done / total * 100)}%</div>
          </div>
          <div style={{ flex: '0 0 200px' }}>
            <div style={{ height: 6, background: 'var(--bg-2)', border: '1px solid var(--rule)' }}>
              <div style={{ height: '100%', width: (done / total * 100) + '%', background: '#0a8754' }}/>
            </div>
          </div>
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          {MILESTONES.map(m => (
            <div key={m.q} style={{ border: '1px solid var(--rule)' }}>
              <div style={{ padding: '10px 18px', borderBottom: '1px solid var(--rule)', background: 'var(--bg-2)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <div style={{ fontSize: 13, fontWeight: 600 }}>{m.q}</div>
                <Mono upper size={9} color="var(--ink-3)">{m.items.filter(i => i.done).length} / {m.items.length} SHIPPED</Mono>
              </div>
              {m.items.map((it, i) => (
                <div key={i} style={{ display: 'grid', gridTemplateColumns: '32px 1fr 110px', gap: 14, padding: '11px 18px', borderBottom: i < m.items.length - 1 ? '1px solid var(--rule-soft)' : 0, alignItems: 'center' }}>
                  <span style={{
                    width: 18, height: 18, borderRadius: '50%',
                    border: '2px solid ' + (it.done ? '#0a8754' : 'var(--ink-3)'),
                    background: it.done ? '#0a8754' : 'transparent',
                    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                    color: '#fff', fontSize: 11, fontWeight: 600,
                  }}>{it.done ? '✓' : ''}</span>
                  <div style={{ fontSize: 12.5, color: it.done ? 'var(--ink-3)' : 'var(--ink)', textDecoration: it.done ? 'line-through' : 'none' }}>{it.l}</div>
                  <Mono upper size={9} color="var(--ink-3)" style={{ textAlign: 'right' }}>{it.tag}</Mono>
                </div>
              ))}
            </div>
          ))}
        </div>
      </div>
    );
  }

  // ─── Cell ────────────────────────────────────────────────────
  function Cell({ label, value, sub, tone }) {
    return (
      <div style={{ padding: '18px 22px', borderRight: '1px solid var(--rule)' }}>
        <Mono upper size={9} color="var(--ink-3)">{label}</Mono>
        <div className="ff-display" style={{ fontSize: 24, fontWeight: 600, letterSpacing: '-0.02em', marginTop: 4, color: tone || 'var(--ink)' }}>{value}</div>
        <div style={{ fontSize: 11, color: 'var(--ink-2)', marginTop: 3 }}>{sub}</div>
      </div>
    );
  }

  // ─── MAIN SCREEN ─────────────────────────────────────────────
  function ScreenFutureProof({ go, payload }) {
    const PageHeader = window.PageHeader;
    const [tab, setTab] = _S(payload?.tab || 'radar');

    const TABS = [
      { k: 'radar',     l: 'Radar' },
      { k: 'signals',   l: 'Signals' },
      { k: 'scenarios', l: 'Scenarios' },
      { k: 'readiness', l: 'Readiness' },
      { k: 'roadmap',   l: 'Roadmap' },
    ];

    return (
      <div>
        {PageHeader && (
          <PageHeader
            eyebrow={['STRATEGY', 'FUTURE-PROOFING', `${SIGNALS.length} SIGNALS`]}
            title="future proof."
            highlight="future proof."
            sub="Forward-looking signals, scenario outlooks, capability readiness, and roadmap. Tracks emerging tech, regulation, business-model shift, and platform risk over a 24-month horizon."
          />
        )}

        <div style={{ borderBottom: '1px solid var(--rule)', display: 'flex', gap: 0, marginBottom: 24 }}>
          {TABS.map(t => (
            <button key={t.k} onClick={() => setTab(t.k)} style={{
              padding: '14px 22px', background: 'transparent', border: 0,
              borderBottom: '2px solid ' + (tab === t.k ? 'var(--ink)' : 'transparent'),
              cursor: 'pointer', color: tab === t.k ? 'var(--ink)' : 'var(--ink-3)',
              fontSize: 13, fontWeight: tab === t.k ? 600 : 400,
            }}>{t.l}</button>
          ))}
        </div>

        {tab === 'radar'     && <RadarTab/>}
        {tab === 'signals'   && <SignalsTab/>}
        {tab === 'scenarios' && <ScenariosTab/>}
        {tab === 'readiness' && <ReadinessTab/>}
        {tab === 'roadmap'   && <RoadmapTab/>}
      </div>
    );
  }

  window.ScreenFutureProof = ScreenFutureProof;
  console.log('[FutureProof] loaded · ' + SIGNALS.length + ' signals · ' + CAPABILITIES.length + ' capabilities');
})();
