// agreement-templates.jsx — Wave 1b: Agreement Template Library
// ────────────────────────────────────────────────────────────────────────
// Templates are the *source* every executed agreement is spawned from.
// One template, many agreements. Versioned. Reviewed by counsel.
// This screen is the legal team's working surface for them.
//
// Schema mapping (astro.agreement_templates):
//   id, agreement_type_code, template_name, description,
//   template_body (markdown w/ {{tokens}}), template_variables (jsonb),
//   template_sections (jsonb), version_number, is_current,
//   reviewed_by, reviewed_at, is_active
//
// Layout: 3-column — kind nav · template list · inspector.
//   • Kind nav lists agreement_type_codes with counts
//   • List shows templates in that kind, with version + status
//   • Inspector tabs: SHELL · BODY · VARIABLES · SECTIONS · VERSIONS · USAGE
//
// Wired:
//   • New from template → dispatches astro-add-agreement w/ template payload
//   • Open in agreement-detail (existing AGREEMENTS spawned from this tpl)
//   • Reachable from screens3 AgreementsView header + agreement-detail
//
// Exports: window.ScreenAgreementTemplates

(function () {
  const { useState, useMemo, useEffect } = React;

  // ─────────── Mock template corpus
  // Real values would come from astro.agreement_templates. Each row is one
  // template, with a small history simulated via altVersions[].
  const TEMPLATES = [
    {
      id: 'tpl_pub_excl_v3',
      code: 'PUBLISHING_EXCLUSIVE',
      kindLabel: 'Publishing · Exclusive',
      name: 'Exclusive Songwriter Agreement — Standard',
      description:
        'Full transfer of copyright in compositions for the term, with admin & sync rights, audit clause, and reversion at term-end after recoupment.',
      version: 3,
      isCurrent: true,
      isActive: true,
      reviewedBy: 'Lasher Sapsford LLP',
      reviewedAt: '2026-02-14',
      createdAt: '2024-08-02',
      updatedBy: 'a.cohen',
      updatedAt: '2026-02-14',
      pages: 14,
      sectionCount: 12,
      variables: [
        { name: 'writer_name',           label: 'Writer legal name',     kind: 'text',     required: true,  ex: 'Margaux Lee' },
        { name: 'writer_address',        label: 'Writer address',         kind: 'address',  required: true },
        { name: 'writer_pro',            label: 'Writer PRO',             kind: 'enum',     required: true,  options:['ASCAP','BMI','SESAC','GMR'], ex:'ASCAP' },
        { name: 'writer_ipi',            label: 'Writer IPI/CAE',         kind: 'numeric',  required: true,  ex:'00731298011' },
        { name: 'pub_share',             label: 'Publisher share',        kind: 'percent',  required: true,  ex:'50' },
        { name: 'writer_share',          label: 'Writer share',           kind: 'percent',  required: true,  ex:'50', derived:'100 − pub_share' },
        { name: 'territory',             label: 'Territory',              kind: 'territory',required: true,  ex:'World' },
        { name: 'term_years',            label: 'Term length (years)',    kind: 'numeric',  required: true,  ex:'3' },
        { name: 'option_periods',        label: 'Option periods',         kind: 'numeric',  required: false, ex:'2 × 1yr' },
        { name: 'advance_amount',        label: 'Advance (USD)',          kind: 'currency', required: true,  ex:'$50,000' },
        { name: 'advance_recoupable',    label: 'Recoupable?',            kind: 'bool',     required: true,  ex:'Yes' },
        { name: 'min_commitment_songs',  label: 'Min commitment (songs)', kind: 'numeric',  required: false, ex:'12' },
        { name: 'reversion_after_years', label: 'Reversion (yrs post-term)',kind:'numeric', required: false, ex:'10' },
        { name: 'audit_window_months',   label: 'Audit window',           kind: 'numeric',  required: true,  ex:'24' },
        { name: 'jurisdiction',          label: 'Governing law',          kind: 'enum',     required: true,  options:['NY','CA','UK','DE'], ex:'NY' },
        { name: 'effective_date',        label: 'Effective date',         kind: 'date',     required: true },
      ],
      sections: [
        { n:'01', title:'Parties & Recitals',         body:'WHEREAS the Writer is engaged in the business of composing musical works…', kind:'boilerplate' },
        { n:'02', title:'Grant of Rights',            body:'Writer hereby irrevocably and exclusively assigns to Publisher in the {{territory}} for the Term…', kind:'core', critical:true },
        { n:'03', title:'Term',                       body:'Initial Term: {{term_years}} years from {{effective_date}}, with {{option_periods}} option periods exercisable by Publisher…', kind:'core' },
        { n:'04', title:'Compensation',               body:'Writer shall receive {{writer_share}}% of Net Publisher Share. Mechanical: 100% of statutory. Performance: per society direct.', kind:'money', critical:true },
        { n:'05', title:'Advance',                    body:'On execution Publisher shall pay {{advance_amount}}, recoupable from {{writer_share}}% royalties.', kind:'money' },
        { n:'06', title:'Minimum Commitment',         body:'Writer shall deliver no fewer than {{min_commitment_songs}} Compositions per Contract Year…', kind:'core' },
        { n:'07', title:'Sync & Synchronization',     body:'Publisher has full authority to license synchronization in audiovisual media without further consent.', kind:'core' },
        { n:'08', title:'Statements & Audit',         body:'Statements rendered semi-annually, payment within 60 days. Audit window {{audit_window_months}} months.', kind:'admin' },
        { n:'09', title:'Reversion',                  body:'{{reversion_after_years}} years post-Term, unrecouped or unexploited Compositions revert at Writer\'s written election.', kind:'core' },
        { n:'10', title:'Warranties & Indemnities',   body:'Writer warrants original authorship, no prior conflicting grant, and indemnifies Publisher…', kind:'boilerplate' },
        { n:'11', title:'Default & Cure',             body:'Material breach: 30-day cure on written notice. Failure to cure → termination.', kind:'admin' },
        { n:'12', title:'Governing Law',              body:'This Agreement is governed by the laws of {{jurisdiction}}, without regard to conflict-of-laws.', kind:'boilerplate' },
      ],
      altVersions: [
        { n:2, label:'v2 · 2025-08-12', notes:'Reduced reversion window from 15 → 10 years; added GMR to PRO enum.', current:false },
        { n:1, label:'v1 · 2024-08-02', notes:'Initial counsel-reviewed draft.', current:false },
      ],
      usageCount: 47,
      lastUsed: '2026-04-12',
    },
    {
      id: 'tpl_pub_admin_v2',
      code: 'PUBLISHING_ADMIN',
      kindLabel: 'Publishing · Admin',
      name: 'Administration Agreement — 3yr / 15%',
      description:
        'Admin-only deal: Writer retains copyright. Publisher collects, registers, audits in exchange for fee.',
      version: 2, isCurrent: true, isActive: true,
      reviewedBy: 'Lasher Sapsford LLP', reviewedAt: '2026-01-08',
      createdAt: '2024-09-30', updatedBy: 'a.cohen', updatedAt: '2026-01-08',
      pages: 9, sectionCount: 9,
      variables: [
        { name:'writer_name', label:'Writer legal name', kind:'text', required:true },
        { name:'admin_fee_pct', label:'Admin fee', kind:'percent', required:true, ex:'15' },
        { name:'territory', label:'Territory', kind:'territory', required:true, ex:'World' },
        { name:'term_years', label:'Term length', kind:'numeric', required:true, ex:'3' },
        { name:'advance_amount', label:'Advance (USD)', kind:'currency', required:false, ex:'$0' },
        { name:'sync_fee_pct', label:'Sync fee', kind:'percent', required:true, ex:'25' },
        { name:'jurisdiction', label:'Governing law', kind:'enum', required:true, options:['NY','CA','UK'], ex:'NY' },
      ],
      sections: [
        { n:'01', title:'Parties & Scope',     body:'Writer engages Publisher to administer rights in the Compositions on a non-exclusive basis…', kind:'boilerplate' },
        { n:'02', title:'Grant of Admin Rights', body:'Writer grants Publisher the right to register, license, collect, audit, and enforce in {{territory}}.', kind:'core', critical:true },
        { n:'03', title:'Term',                body:'{{term_years}} years; auto-renewing 1-year periods unless 90 days written notice.', kind:'core' },
        { n:'04', title:'Admin Fee',           body:'Publisher retains {{admin_fee_pct}}% of all Net Receipts as administration fee. Sync: {{sync_fee_pct}}%.', kind:'money', critical:true },
        { n:'05', title:'Advance',             body:'If applicable: {{advance_amount}} recoupable from Net Receipts.', kind:'money' },
        { n:'06', title:'Statements',          body:'Quarterly statements within 60 days of period end.', kind:'admin' },
        { n:'07', title:'Reversion',           body:'On termination, all admin rights revert to Writer. Pipeline collected post-term remitted within 90 days.', kind:'core' },
        { n:'08', title:'Warranties',          body:'Writer warrants ownership and authority to grant rights herein.', kind:'boilerplate' },
        { n:'09', title:'Governing Law',       body:'This Agreement is governed by the laws of {{jurisdiction}}.', kind:'boilerplate' },
      ],
      altVersions: [
        { n:1, label:'v1 · 2024-09-30', notes:'Initial draft.', current:false },
      ],
      usageCount: 31,
      lastUsed: '2026-04-22',
    },
    {
      id: 'tpl_pub_cowrite_v1',
      code: 'PUBLISHING_COWRITE',
      kindLabel: 'Publishing · Co-write',
      name: 'Co-write Split Sheet — Pro Rata',
      description:
        'Lightweight split agreement for ad-hoc collaborations. Establishes split, work-for-hire status, and admin assignment per writer.',
      version: 1, isCurrent: true, isActive: true,
      reviewedBy: 'Lasher Sapsford LLP', reviewedAt: '2025-11-04',
      createdAt: '2025-11-04', updatedBy: 'm.lee', updatedAt: '2025-11-04',
      pages: 3, sectionCount: 5,
      variables: [
        { name:'work_title', label:'Work title', kind:'text', required:true },
        { name:'cowriters', label:'Co-writers (array)', kind:'list', required:true },
        { name:'splits',    label:'Splits per writer', kind:'percent_array', required:true },
        { name:'session_date', label:'Session date', kind:'date', required:true },
        { name:'wfh',       label:'Work-for-hire?', kind:'bool', required:true, ex:'No' },
      ],
      sections: [
        { n:'01', title:'Composition',     body:'Writers co-authored "{{work_title}}" on {{session_date}}.', kind:'core' },
        { n:'02', title:'Splits',          body:'Splits sum to 100%. Each writer\'s share: {{splits}}.', kind:'core', critical:true },
        { n:'03', title:'Admin',           body:'Each writer\'s share is administered by their respective publisher of record.', kind:'admin' },
        { n:'04', title:'Work-for-hire',   body:'WFH status: {{wfh}}. If yes, attached employer indemnifies.', kind:'core' },
        { n:'05', title:'Signatures',      body:'Counterparts; e-signature acceptable per ESIGN.', kind:'boilerplate' },
      ],
      altVersions: [],
      usageCount: 184,
      lastUsed: '2026-04-29',
    },
    {
      id: 'tpl_rec_excl_v4',
      code: 'RECORDING_EXCLUSIVE',
      kindLabel: 'Recording · Exclusive',
      name: 'Exclusive Recording Agreement — Standard',
      description:
        'Master rights vest in label for term. Royalty schedule, packaging deduction, controlled comp, free goods, all-in producer.',
      version: 4, isCurrent: true, isActive: true,
      reviewedBy: 'Lasher Sapsford LLP', reviewedAt: '2026-03-21',
      createdAt: '2023-05-11', updatedBy: 'k.davis', updatedAt: '2026-03-21',
      pages: 22, sectionCount: 18,
      variables: [
        { name:'artist_name', label:'Artist legal name', kind:'text', required:true },
        { name:'p_and_a',     label:'Featured artist royalty', kind:'percent', required:true, ex:'18' },
        { name:'producer_share', label:'Producer share (all-in)', kind:'percent', required:true, ex:'4' },
        { name:'packaging_deduction', label:'Packaging deduction', kind:'percent', required:true, ex:'25' },
        { name:'free_goods', label:'Free goods %', kind:'percent', required:true, ex:'15' },
        { name:'controlled_comp', label:'Controlled comp rate', kind:'percent', required:true, ex:'75' },
        { name:'min_albums', label:'Albums (firm)', kind:'numeric', required:true, ex:'2' },
        { name:'option_albums', label:'Albums (option)', kind:'numeric', required:false, ex:'3' },
        { name:'advance_amount', label:'Advance (USD)', kind:'currency', required:true, ex:'$200,000' },
        { name:'recording_fund', label:'Recording fund', kind:'currency', required:true, ex:'$150,000' },
        { name:'territory', label:'Territory', kind:'territory', required:true, ex:'World' },
        { name:'jurisdiction', label:'Governing law', kind:'enum', required:true, options:['NY','CA','UK'], ex:'NY' },
      ],
      sections: [
        { n:'01', title:'Engagement',                body:'Label engages Artist on an exclusive basis…', kind:'core' },
        { n:'02', title:'Recording Commitment',      body:'Firm: {{min_albums}} Album(s). Option(s): {{option_albums}} at Label\'s sole discretion.', kind:'core', critical:true },
        { n:'03', title:'Term',                      body:'Term commences on Effective Date and continues until 12 months after Delivery of the last Recording.', kind:'core' },
        { n:'04', title:'Recording Fund',            body:'{{recording_fund}} per Album, all-in (recoupable).', kind:'money' },
        { n:'05', title:'Royalty — Featured Artist', body:'{{p_and_a}}% of SRLP, less Packaging Deduction of {{packaging_deduction}}% and Free Goods of {{free_goods}}%.', kind:'money', critical:true },
        { n:'06', title:'Royalty — Producer',        body:'{{producer_share}}% all-in, included within Featured Artist royalty.', kind:'money' },
        { n:'07', title:'Controlled Composition',    body:'Mechanical license issued at {{controlled_comp}}% of statutory rate.', kind:'money', critical:true },
        { n:'08', title:'Advance',                   body:'{{advance_amount}} on signing, recoupable from royalties.', kind:'money' },
        { n:'09', title:'Ownership of Masters',      body:'All Masters created during Term are works made for hire; Label is sole author.', kind:'core', critical:true },
        { n:'10', title:'Exclusivity',               body:'Artist shall not record for any third party during Term without Label written consent.', kind:'core' },
        { n:'11', title:'Marketing & Promo',         body:'Artist provides reasonable promotional services; tour support as separately agreed.', kind:'admin' },
        { n:'12', title:'Statements & Audit',        body:'Semi-annual; audit window 24 months; once-per-period.', kind:'admin' },
        { n:'13', title:'Tour Support',              body:'Up to 50% of approved tour-deficit shortfall, recoupable from royalties.', kind:'money' },
        { n:'14', title:'Side Artist Provisions',    body:'Artist may guest on third-party records subject to Label approval, name credit per industry custom.', kind:'core' },
        { n:'15', title:'Re-record Restriction',     body:'Artist shall not re-record any Master for 5 years post-Term.', kind:'core', critical:true },
        { n:'16', title:'Suspension & Force Majeure',body:'Standard provisions for default, suspension, and force majeure events.', kind:'admin' },
        { n:'17', title:'Warranties & Indemnities',  body:'Mutual warranties. Indemnification with notice & defense.', kind:'boilerplate' },
        { n:'18', title:'Governing Law',             body:'This Agreement is governed by the laws of {{jurisdiction}}.', kind:'boilerplate' },
      ],
      altVersions: [
        { n:3, label:'v3 · 2025-09-14', notes:'Removed CD-era 360 carve-outs; added DSP NPR clarification.', current:false },
        { n:2, label:'v2 · 2024-04-02', notes:'Adjusted controlled-comp default to 75%.', current:false },
        { n:1, label:'v1 · 2023-05-11', notes:'Initial draft.', current:false },
      ],
      usageCount: 22,
      lastUsed: '2026-03-30',
    },
    {
      id: 'tpl_rec_distrib_v2',
      code: 'RECORDING_DISTRIBUTION',
      kindLabel: 'Recording · Distribution',
      name: 'Distribution Agreement — Master Rights Retained',
      description:
        'Artist retains masters; label distributes & markets. Net-receipts split, marketing recoupable, sub-licensee passthrough.',
      version: 2, isCurrent: true, isActive: true,
      reviewedBy: 'Lasher Sapsford LLP', reviewedAt: '2026-02-26',
      createdAt: '2024-12-01', updatedBy: 'k.davis', updatedAt: '2026-02-26',
      pages: 11, sectionCount: 10,
      variables: [
        { name:'artist_name', label:'Artist legal name', kind:'text', required:true },
        { name:'distrib_fee', label:'Distribution fee', kind:'percent', required:true, ex:'15' },
        { name:'marketing_recoupable_cap', label:'Marketing recoup cap', kind:'currency', required:true, ex:'$100,000' },
        { name:'territory', label:'Territory', kind:'territory', required:true, ex:'World' },
        { name:'term_years', label:'Term length', kind:'numeric', required:true, ex:'5' },
        { name:'jurisdiction', label:'Governing law', kind:'enum', required:true, options:['NY','CA','UK'], ex:'NY' },
      ],
      sections: [
        { n:'01', title:'Scope',                  body:'Label distributes Artist-owned Recordings.', kind:'core' },
        { n:'02', title:'Term',                   body:'{{term_years}} years from Delivery of first Recording.', kind:'core' },
        { n:'03', title:'Distribution Fee',       body:'{{distrib_fee}}% of Net Receipts.', kind:'money', critical:true },
        { n:'04', title:'Marketing Spend',        body:'Capped at {{marketing_recoupable_cap}}, fully recoupable.', kind:'money' },
        { n:'05', title:'Sublicensees',           body:'Net-of-net pass-through, no double-deduction.', kind:'admin' },
        { n:'06', title:'Ownership',              body:'Artist retains all Masters and copyrights.', kind:'core', critical:true },
        { n:'07', title:'Statements',             body:'Quarterly, 45 days post-period.', kind:'admin' },
        { n:'08', title:'Audit',                  body:'Annual audit right; 24-month window.', kind:'admin' },
        { n:'09', title:'Termination',            body:'Either party on 90-day notice if material breach uncured.', kind:'admin' },
        { n:'10', title:'Governing Law',          body:'Laws of {{jurisdiction}}.', kind:'boilerplate' },
      ],
      altVersions: [
        { n:1, label:'v1 · 2024-12-01', notes:'Initial.', current:false },
      ],
      usageCount: 14,
      lastUsed: '2026-04-18',
    },
    {
      id: 'tpl_lic_sync_master_v3',
      code: 'LICENSE_SYNC_MASTER',
      kindLabel: 'License · Sync (Master)',
      name: 'Sync License — Master Side · Standard',
      description:
        'One-time master-side sync grant. Term, territory, media-type matrix, MFN handling, novel-use carve-out.',
      version: 3, isCurrent: true, isActive: true,
      reviewedBy: 'Lasher Sapsford LLP', reviewedAt: '2026-04-02',
      createdAt: '2024-02-19', updatedBy: 'a.cohen', updatedAt: '2026-04-02',
      pages: 6, sectionCount: 8,
      variables: [
        { name:'licensee_name', label:'Licensee', kind:'text', required:true },
        { name:'production_title', label:'Production title', kind:'text', required:true },
        { name:'production_type', label:'Type', kind:'enum', required:true, options:['Feature','TV Series','Ad','Trailer','Game','Promo','UGC platform'], ex:'TV Series' },
        { name:'media_scope',   label:'Media types', kind:'multi-enum', required:true, options:['All Media','Theatrical','Linear TV','SVOD','AVOD','Internet','Out-of-home','Festivals','Trailers','Promotional'] },
        { name:'territory',     label:'Territory', kind:'territory', required:true, ex:'World' },
        { name:'term_length',   label:'Term', kind:'enum', required:true, options:['Perpetual','15 years','10 years','5 years','3 years','1 year'], ex:'5 years' },
        { name:'sync_fee',      label:'Sync fee (USD)', kind:'currency', required:true, ex:'$15,000' },
        { name:'mfn',           label:'MFN with publisher?', kind:'bool', required:true, ex:'Yes' },
        { name:'novel_use',     label:'AI/novel-use carve-out', kind:'bool', required:true, ex:'Yes' },
      ],
      sections: [
        { n:'01', title:'Grant',          body:'Non-exclusive license to synchronize the Master with {{production_title}}.', kind:'core', critical:true },
        { n:'02', title:'Media',          body:'Permitted media: {{media_scope}}.', kind:'core' },
        { n:'03', title:'Territory & Term', body:'{{territory}} · {{term_length}}.', kind:'core' },
        { n:'04', title:'Fee',            body:'{{sync_fee}} payable on execution.', kind:'money', critical:true },
        { n:'05', title:'MFN',            body:'If {{mfn}}, fee adjusts to match publisher-side fee within 30 days of notice.', kind:'core' },
        { n:'06', title:'Novel Use',      body:'If {{novel_use}}, AI training, generative remix, and similar uses are reserved and require separate license.', kind:'core' },
        { n:'07', title:'Credits',        body:'On-screen credit per industry custom; cue-sheet filing required.', kind:'admin' },
        { n:'08', title:'Standards',      body:'Standard reps, warranties, indemnities, and governing law.', kind:'boilerplate' },
      ],
      altVersions: [
        { n:2, label:'v2 · 2025-06-15', notes:'Added novel-use / AI carve-out.', current:false },
        { n:1, label:'v1 · 2024-02-19', notes:'Initial.', current:false },
      ],
      usageCount: 91,
      lastUsed: '2026-04-30',
    },
    {
      id: 'tpl_lic_sync_pub_v2',
      code: 'LICENSE_SYNC_PUB',
      kindLabel: 'License · Sync (Pub)',
      name: 'Sync License — Publisher Side · Standard',
      description:
        'One-time publisher-side sync grant. Mirrors master template structure for MFN compatibility.',
      version: 2, isCurrent: true, isActive: true,
      reviewedBy: 'Lasher Sapsford LLP', reviewedAt: '2026-04-02',
      createdAt: '2024-02-19', updatedBy: 'a.cohen', updatedAt: '2026-04-02',
      pages: 6, sectionCount: 8,
      variables: [
        { name:'licensee_name', label:'Licensee', kind:'text', required:true },
        { name:'work_title',  label:'Work title', kind:'text', required:true },
        { name:'territory',  label:'Territory', kind:'territory', required:true, ex:'World' },
        { name:'sync_fee',   label:'Sync fee', kind:'currency', required:true, ex:'$15,000' },
        { name:'mfn',         label:'MFN with master?', kind:'bool', required:true, ex:'Yes' },
      ],
      sections: [
        { n:'01', title:'Grant',          body:'Non-exclusive license to synchronize the Composition.', kind:'core', critical:true },
        { n:'02', title:'Territory',      body:'{{territory}}.', kind:'core' },
        { n:'03', title:'Fee',            body:'{{sync_fee}} on execution.', kind:'money', critical:true },
        { n:'04', title:'MFN',            body:'Mirrors master.', kind:'core' },
        { n:'05', title:'Cue-sheet',      body:'Licensee delivers cue-sheet within 60 days of first exhibition.', kind:'admin' },
        { n:'06', title:'Novel Use',      body:'AI/generative use reserved.', kind:'core' },
        { n:'07', title:'Credits',        body:'Per industry custom.', kind:'admin' },
        { n:'08', title:'Standards',      body:'Standard boilerplate.', kind:'boilerplate' },
      ],
      altVersions: [
        { n:1, label:'v1 · 2024-02-19', notes:'Initial.', current:false },
      ],
      usageCount: 88,
      lastUsed: '2026-04-30',
    },
    {
      id: 'tpl_lic_mech_v1',
      code: 'LICENSE_MECHANICAL',
      kindLabel: 'License · Mechanical',
      name: 'Mechanical License — Compulsory',
      description:
        'Standard 17 USC §115 compulsory mech for cover recordings. Statutory rate, accounting, NOI handling.',
      version: 1, isCurrent: true, isActive: true,
      reviewedBy: 'Lasher Sapsford LLP', reviewedAt: '2025-04-10',
      createdAt: '2025-04-10', updatedBy: 'a.cohen', updatedAt: '2025-04-10',
      pages: 4, sectionCount: 6,
      variables: [
        { name:'licensee_name', label:'Licensee', kind:'text', required:true },
        { name:'work_title', label:'Work', kind:'text', required:true },
        { name:'release_format', label:'Format', kind:'enum', required:true, options:['Physical','Digital DPD','Streaming'], ex:'Streaming' },
        { name:'configuration', label:'Configuration', kind:'enum', required:true, options:['CD','Vinyl','Cassette','Digital'], ex:'Digital' },
        { name:'rate', label:'Rate', kind:'enum', required:true, options:['Statutory','75% statutory','Negotiated'], ex:'Statutory' },
      ],
      sections: [
        { n:'01', title:'Grant',     body:'Compulsory mech under 17 USC §115 for {{work_title}}.', kind:'core', critical:true },
        { n:'02', title:'Rate',      body:'{{rate}} rate per unit/stream.', kind:'money', critical:true },
        { n:'03', title:'Format',    body:'{{configuration}} / {{release_format}}.', kind:'core' },
        { n:'04', title:'Statements',body:'Monthly within 20 days, per §115.', kind:'admin' },
        { n:'05', title:'Audit',     body:'Standard §115 audit rights.', kind:'admin' },
        { n:'06', title:'Termination', body:'Per §115(c).', kind:'boilerplate' },
      ],
      altVersions: [],
      usageCount: 412,
      lastUsed: '2026-04-30',
    },
    {
      id: 'tpl_subpub_v3',
      code: 'SUBPUBLISHING',
      kindLabel: 'Subpublishing',
      name: 'Subpublishing Agreement — Territory Pack',
      description:
        'Foreign territory subpub deal. At-source vs. receipts split, cover-record carve-out, sync approval rights, audit pass-through.',
      version: 3, isCurrent: true, isActive: true,
      reviewedBy: 'Lasher Sapsford LLP', reviewedAt: '2026-03-12',
      createdAt: '2024-01-20', updatedBy: 'a.cohen', updatedAt: '2026-03-12',
      pages: 10, sectionCount: 11,
      variables: [
        { name:'subpub_name', label:'Subpublisher', kind:'text', required:true },
        { name:'territory_list', label:'Territory list', kind:'territory', required:true, ex:'EU + UK' },
        { name:'pub_share_pct', label:'Publisher share (at-source)', kind:'percent', required:true, ex:'80' },
        { name:'subpub_share_pct', label:'Subpub share', kind:'percent', required:true, ex:'20' },
        { name:'cover_pct', label:'Cover record share', kind:'percent', required:false, ex:'15' },
        { name:'sync_approval', label:'Sync approval required', kind:'bool', required:true, ex:'Yes' },
        { name:'term_years', label:'Term', kind:'numeric', required:true, ex:'3' },
        { name:'jurisdiction', label:'Governing law', kind:'enum', required:true, options:['NY','UK','DE'], ex:'UK' },
      ],
      sections: [
        { n:'01', title:'Grant',            body:'Non-exclusive subpub appointment in {{territory_list}}.', kind:'core', critical:true },
        { n:'02', title:'Term',             body:'{{term_years}} years.', kind:'core' },
        { n:'03', title:'Splits — Original',body:'At-source: Publisher {{pub_share_pct}}% / Subpub {{subpub_share_pct}}%.', kind:'money', critical:true },
        { n:'04', title:'Splits — Covers',  body:'Cover records: {{cover_pct}}% to subpub.', kind:'money' },
        { n:'05', title:'Sync Approval',    body:'Sync requires approval: {{sync_approval}}.', kind:'core' },
        { n:'06', title:'Registrations',    body:'Subpub registers Works with local society within 60 days.', kind:'admin' },
        { n:'07', title:'Statements',       body:'Quarterly, 90 days post-period.', kind:'admin' },
        { n:'08', title:'Audit',            body:'Pass-through audit right, 24-month window.', kind:'admin' },
        { n:'09', title:'Reversion',        body:'On termination, all rights revert immediately. Pipeline 6 months.', kind:'core' },
        { n:'10', title:'Warranties',       body:'Standard.', kind:'boilerplate' },
        { n:'11', title:'Governing Law',    body:'{{jurisdiction}}.', kind:'boilerplate' },
      ],
      altVersions: [
        { n:2, label:'v2 · 2025-04-22', notes:'Switched default to at-source from receipts.', current:false },
        { n:1, label:'v1 · 2024-01-20', notes:'Initial.', current:false },
      ],
      usageCount: 18,
      lastUsed: '2026-04-08',
    },
    {
      id: 'tpl_producer_excl_v2',
      code: 'PRODUCER_EXCLUSIVE',
      kindLabel: 'Producer · Exclusive',
      name: 'Producer Agreement — Work-for-hire',
      description:
        'Producer engaged on WFH basis. Album fee, all-in royalty, masters owned by Label.',
      version: 2, isCurrent: true, isActive: true,
      reviewedBy: 'Lasher Sapsford LLP', reviewedAt: '2026-01-30',
      createdAt: '2024-06-01', updatedBy: 'k.davis', updatedAt: '2026-01-30',
      pages: 8, sectionCount: 7,
      variables: [
        { name:'producer_name', label:'Producer', kind:'text', required:true },
        { name:'producer_fee',  label:'Fee per Master', kind:'currency', required:true, ex:'$10,000' },
        { name:'producer_royalty', label:'All-in producer royalty', kind:'percent', required:true, ex:'4' },
        { name:'point_floor',   label:'Royalty floor', kind:'percent', required:false, ex:'3' },
      ],
      sections: [
        { n:'01', title:'Engagement',     body:'Producer engaged on WFH basis.', kind:'core', critical:true },
        { n:'02', title:'Compensation',   body:'{{producer_fee}} per Master delivered. Royalty: {{producer_royalty}}% all-in.', kind:'money', critical:true },
        { n:'03', title:'Ownership',      body:'Masters created hereunder are works made for hire; Label is sole author.', kind:'core', critical:true },
        { n:'04', title:'Credits',        body:'"Produced by" on record packaging and DSP metadata.', kind:'admin' },
        { n:'05', title:'Recoupment',     body:'Producer royalty payable retroactively from Record One after artist recoupment.', kind:'money' },
        { n:'06', title:'Mixer & Engineer',body:'Not included; separate WFH letters required.', kind:'admin' },
        { n:'07', title:'Standards',      body:'Standard boilerplate.', kind:'boilerplate' },
      ],
      altVersions: [
        { n:1, label:'v1 · 2024-06-01', notes:'Initial.', current:false },
      ],
      usageCount: 38,
      lastUsed: '2026-04-19',
    },
    {
      id: 'tpl_pub_excl_v2_legacy',
      code: 'PUBLISHING_EXCLUSIVE',
      kindLabel: 'Publishing · Exclusive',
      name: 'Exclusive Songwriter Agreement — LEGACY 15-yr reversion',
      description:
        'Pre-2026 form, retained for in-flight deals signed under old terms.',
      version: 2, isCurrent: false, isActive: false,
      reviewedBy: 'Lasher Sapsford LLP', reviewedAt: '2025-08-12',
      createdAt: '2025-08-12', updatedBy: 'a.cohen', updatedAt: '2026-02-14',
      pages: 14, sectionCount: 12, variables: [], sections: [],
      altVersions: [{ n:1, label:'v1', notes:'Original.', current:false }],
      usageCount: 11, lastUsed: '2026-01-10',
    },
  ];

  // Group by code
  const KIND_ORDER = [
    'PUBLISHING_EXCLUSIVE','PUBLISHING_ADMIN','PUBLISHING_COWRITE',
    'RECORDING_EXCLUSIVE','RECORDING_DISTRIBUTION',
    'LICENSE_SYNC_MASTER','LICENSE_SYNC_PUB','LICENSE_MECHANICAL',
    'SUBPUBLISHING','PRODUCER_EXCLUSIVE',
  ];
  const KIND_LABELS = {
    PUBLISHING_EXCLUSIVE: { label:'Publishing — Exclusive', cluster:'Publishing' },
    PUBLISHING_ADMIN:     { label:'Publishing — Admin',     cluster:'Publishing' },
    PUBLISHING_COWRITE:   { label:'Publishing — Co-write',  cluster:'Publishing' },
    RECORDING_EXCLUSIVE:  { label:'Recording — Exclusive',  cluster:'Recording' },
    RECORDING_DISTRIBUTION:{ label:'Recording — Distribution', cluster:'Recording' },
    LICENSE_SYNC_MASTER:  { label:'Sync — Master',          cluster:'Licensing' },
    LICENSE_SYNC_PUB:     { label:'Sync — Publisher',       cluster:'Licensing' },
    LICENSE_MECHANICAL:   { label:'Mechanical',             cluster:'Licensing' },
    SUBPUBLISHING:        { label:'Subpublishing',          cluster:'Publishing' },
    PRODUCER_EXCLUSIVE:   { label:'Producer',               cluster:'Recording' },
  };

  // ─────────── Helpers
  const fmtInt = (n) => n.toLocaleString('en-US');

  function VarKindBadge({ kind }) {
    const map = {
      text:'TEXT', address:'ADDR', enum:'ENUM', 'multi-enum':'M.ENUM', numeric:'NUM',
      percent:'%', currency:'$', territory:'GEO', date:'DATE', bool:'BOOL',
      list:'LIST', 'percent_array':'%×N',
    };
    return (
      <span className="ff-mono" style={{
        fontSize:9, padding:'2px 6px', background:'var(--bg-2)', border:'1px solid var(--rule)',
        color:'var(--ink-2)', letterSpacing:'.06em',
      }}>{map[kind] || kind.toUpperCase()}</span>
    );
  }

  function SectionKindDot({ kind, critical }) {
    const c = kind === 'core'         ? 'var(--ink)' :
              kind === 'money'        ? '#c95818' :
              kind === 'admin'        ? '#1f4ed8' :
                                        'var(--ink-3)';
    return (
      <span style={{ display:'inline-flex', alignItems:'center', gap:6 }}>
        <span style={{ width:8, height:8, background:c, borderRadius:'50%', flexShrink:0,
          outline: critical ? '2px solid var(--accent)' : 'none', outlineOffset:1 }}/>
        <span className="ff-mono upper" style={{ fontSize:9, color:'var(--ink-3)', letterSpacing:'.08em' }}>
          {kind}{critical ? ' · CRITICAL' : ''}
        </span>
      </span>
    );
  }

  // ─────────── Inspector
  function Inspector({ tpl, go }) {
    const [tab, setTab] = useState('shell');

    if (!tpl) {
      return (
        <div style={{ padding:'80px 40px', textAlign:'center', color:'var(--ink-3)' }}>
          <div className="ff-display" style={{ fontSize:24, color:'var(--ink-2)', marginBottom:6, letterSpacing:'-0.02em' }}>
            Select a template
          </div>
          <div className="ff-mono" style={{ fontSize:11, letterSpacing:'.04em' }}>
            Choose one from the list to inspect, version, or send for signature.
          </div>
        </div>
      );
    }

    const tabs = [
      { k:'shell',     l:'01 · OVERVIEW' },
      { k:'body',      l:'02 · CLAUSES' },
      { k:'variables', l:`03 · VARIABLES (${tpl.variables.length})` },
      { k:'versions',  l:`04 · VERSIONS (${tpl.altVersions.length + 1})` },
      { k:'usage',     l:`05 · USAGE (${tpl.usageCount})` },
    ];

    return (
      <div>
        {/* Header */}
        <div style={{ padding:'24px 28px 18px', borderBottom:'1px solid var(--rule)' }}>
          <div className="ff-mono upper" style={{ fontSize:9, color:'var(--ink-3)', letterSpacing:'.12em', marginBottom:8 }}>
            {KIND_LABELS[tpl.code]?.label || tpl.code} · {tpl.id}
          </div>
          <h1 className="ff-display" style={{ fontSize:28, fontWeight:600, letterSpacing:'-0.02em', margin:0, lineHeight:1.2 }}>
            {tpl.name}
          </h1>
          <p style={{ fontSize:13, color:'var(--ink-2)', margin:'10px 0 14px', lineHeight:1.55, maxWidth:680 }}>
            {tpl.description}
          </p>
          <div style={{ display:'flex', gap:8, flexWrap:'wrap' }}>
            {tpl.isCurrent && tpl.isActive && (
              <span className="ff-mono upper" style={{ fontSize:9, padding:'4px 8px', background:'#1a4d1a', color:'#fff', letterSpacing:'.1em', fontWeight:600 }}>
                CURRENT · v{tpl.version}
              </span>
            )}
            {!tpl.isCurrent && (
              <span className="ff-mono upper" style={{ fontSize:9, padding:'4px 8px', background:'var(--bg-2)', border:'1px solid var(--rule)', color:'var(--ink-3)', letterSpacing:'.1em' }}>
                LEGACY · v{tpl.version}
              </span>
            )}
            {!tpl.isActive && (
              <span className="ff-mono upper" style={{ fontSize:9, padding:'4px 8px', background:'#7a1f1f', color:'#fff', letterSpacing:'.1em', fontWeight:600 }}>
                INACTIVE
              </span>
            )}
            <span className="ff-mono upper" style={{ fontSize:9, padding:'4px 8px', background:'var(--bg-2)', border:'1px solid var(--rule)', color:'var(--ink-3)', letterSpacing:'.1em' }}>
              {tpl.pages} PP · {tpl.sectionCount} §
            </span>
            <span className="ff-mono upper" style={{ fontSize:9, padding:'4px 8px', background:'var(--bg-2)', border:'1px solid var(--rule)', color:'var(--ink-3)', letterSpacing:'.1em' }}>
              REVIEWED {tpl.reviewedAt} · {tpl.reviewedBy}
            </span>
          </div>
        </div>

        {/* Action bar */}
        <div style={{ padding:'14px 28px', borderBottom:'1px solid var(--rule)', display:'flex', gap:10, flexWrap:'wrap', alignItems:'center', background:'var(--bg-2)' }}>
          <button onClick={() => {
            // Spawn new agreement from this template
            window.dispatchEvent(new CustomEvent('astro-add-agreement', { detail:{ template: tpl.id, code: tpl.code } }));
          }} disabled={!tpl.isActive}
            className="ff-mono upper" style={{
              padding:'10px 16px', fontSize:11, letterSpacing:'.08em', fontWeight:600,
              background:'var(--ink)', color:'var(--bg)', border:0,
              cursor: tpl.isActive ? 'pointer' : 'not-allowed', opacity: tpl.isActive ? 1 : 0.4,
            }}>
            ↑ NEW AGREEMENT FROM TEMPLATE
          </button>
          <button className="ff-mono upper" style={{
            padding:'10px 14px', fontSize:11, letterSpacing:'.08em', fontWeight:600,
            background:'transparent', color:'var(--ink)', border:'1px solid var(--rule)', cursor:'pointer',
          }}>
            FORK NEW VERSION
          </button>
          <button className="ff-mono upper" style={{
            padding:'10px 14px', fontSize:11, letterSpacing:'.08em', fontWeight:600,
            background:'transparent', color:'var(--ink)', border:'1px solid var(--rule)', cursor:'pointer',
          }}>
            EXPORT .DOCX
          </button>
          <button className="ff-mono upper" style={{
            padding:'10px 14px', fontSize:11, letterSpacing:'.08em', fontWeight:600,
            background:'transparent', color:'var(--ink)', border:'1px solid var(--rule)', cursor:'pointer',
          }}>
            SEND TO COUNSEL
          </button>
          <span style={{ flex:1 }}/>
          <span className="ff-mono" style={{ fontSize:10, color:'var(--ink-3)', letterSpacing:'.04em' }}>
            updated {tpl.updatedAt} · {tpl.updatedBy}
          </span>
        </div>

        {/* Tabs */}
        <div style={{ borderBottom:'1px solid var(--rule)', display:'flex', padding:'0 28px' }}>
          {tabs.map(t => (
            <button key={t.k} onClick={() => setTab(t.k)} className="ff-mono upper"
              style={{
                padding:'14px 18px', fontSize:10, letterSpacing:'.1em', fontWeight: tab===t.k ? 700 : 500,
                background:'transparent', border:0, color: tab===t.k ? 'var(--ink)' : 'var(--ink-3)',
                borderBottom: tab===t.k ? '2px solid var(--ink)' : '2px solid transparent',
                marginBottom:-1, cursor:'pointer',
              }}>{t.l}</button>
          ))}
        </div>

        {/* Tab content */}
        <div style={{ padding:'28px' }}>
          {tab === 'shell' && <ShellTab tpl={tpl}/>}
          {tab === 'body' && <BodyTab tpl={tpl}/>}
          {tab === 'variables' && <VariablesTab tpl={tpl}/>}
          {tab === 'versions' && <VersionsTab tpl={tpl}/>}
          {tab === 'usage' && <UsageTab tpl={tpl} go={go}/>}
        </div>
      </div>
    );
  }

  // ───── Tab: Overview / shell
  function ShellTab({ tpl }) {
    return (
      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:32 }}>
        <div>
          <div className="ff-mono upper" style={{ fontSize:10, color:'var(--ink-3)', letterSpacing:'.12em', marginBottom:14 }}>
            STRUCTURE AT A GLANCE
          </div>
          <div style={{ border:'1px solid var(--rule)' }}>
            {tpl.sections.map((s,i) => (
              <div key={s.n} style={{
                padding:'10px 14px',
                borderBottom: i < tpl.sections.length-1 ? '1px solid var(--rule-soft)' : 'none',
                display:'grid', gridTemplateColumns:'40px 1fr 130px', gap:10, alignItems:'center',
              }}>
                <span className="ff-mono num" style={{ fontSize:11, color:'var(--ink-3)' }}>{s.n}</span>
                <span style={{ fontSize:13, fontWeight:500 }}>
                  {s.title}
                  {s.critical && <span className="ff-mono upper" style={{ marginLeft:8, fontSize:9, padding:'1px 5px', background:'var(--accent)', color:'var(--accent-ink)', letterSpacing:'.08em', fontWeight:600 }}>!</span>}
                </span>
                <SectionKindDot kind={s.kind} critical={s.critical}/>
              </div>
            ))}
          </div>
        </div>
        <div>
          <div className="ff-mono upper" style={{ fontSize:10, color:'var(--ink-3)', letterSpacing:'.12em', marginBottom:14 }}>
            REQUIRED VARIABLES
          </div>
          <div style={{ border:'1px solid var(--rule)' }}>
            {tpl.variables.filter(v => v.required).map((v,i,arr) => (
              <div key={v.name} style={{
                padding:'10px 14px',
                borderBottom: i < arr.length-1 ? '1px solid var(--rule-soft)' : 'none',
                display:'grid', gridTemplateColumns:'1fr 80px', gap:10, alignItems:'center',
              }}>
                <div>
                  <div style={{ fontSize:13, fontWeight:500 }}>{v.label}</div>
                  <div className="ff-mono" style={{ fontSize:10, color:'var(--ink-3)', marginTop:2 }}>
                    {`{{${v.name}}}`}{v.ex ? ` · e.g. ${v.ex}` : ''}
                  </div>
                </div>
                <div style={{ textAlign:'right' }}><VarKindBadge kind={v.kind}/></div>
              </div>
            ))}
            {tpl.variables.filter(v => v.required).length === 0 && (
              <div style={{ padding:'14px', color:'var(--ink-3)', fontSize:12 }}>
                No required variables — pure boilerplate.
              </div>
            )}
          </div>

          <div className="ff-mono upper" style={{ fontSize:10, color:'var(--ink-3)', letterSpacing:'.12em', margin:'24px 0 12px' }}>
            CRITICAL PROVISIONS · COUNSEL FLAGGED
          </div>
          <ul style={{ margin:0, padding:'0 0 0 16px', fontSize:13, lineHeight:1.6, color:'var(--ink-2)' }}>
            {tpl.sections.filter(s => s.critical).map(s => (
              <li key={s.n}><strong>§{s.n} {s.title}</strong></li>
            ))}
            {tpl.sections.filter(s => s.critical).length === 0 && (
              <li style={{ color:'var(--ink-3)', listStyle:'none', marginLeft:-16 }}>No counsel-flagged provisions on this template.</li>
            )}
          </ul>
        </div>
      </div>
    );
  }

  // ───── Tab: Body / clauses
  function BodyTab({ tpl }) {
    return (
      <div style={{ maxWidth: 800 }}>
        <div className="ff-mono upper" style={{ fontSize:10, color:'var(--ink-3)', letterSpacing:'.12em', marginBottom:18 }}>
          FULL BODY · TOKENS HIGHLIGHTED · CLICK TO COPY
        </div>
        {tpl.sections.map(s => (
          <div key={s.n} style={{ marginBottom:24, paddingBottom:18, borderBottom:'1px solid var(--rule-soft)' }}>
            <div style={{ display:'flex', alignItems:'baseline', gap:14, marginBottom:8 }}>
              <span className="ff-mono num" style={{ fontSize:13, color:'var(--ink-3)', fontWeight:600 }}>§{s.n}</span>
              <h3 style={{ fontSize:16, fontWeight:600, margin:0, letterSpacing:'-0.01em' }}>{s.title}</h3>
              <span style={{ flex:1 }}/>
              <SectionKindDot kind={s.kind} critical={s.critical}/>
            </div>
            <p style={{ fontSize:13, color:'var(--ink)', lineHeight:1.65, margin:0, fontFamily:'Georgia, serif' }}>
              {s.body.split(/(\{\{[^}]+\}\})/).map((part, i) =>
                /^\{\{[^}]+\}\}$/.test(part) ? (
                  <span key={i} className="ff-mono"
                    onClick={() => { try { navigator.clipboard.writeText(part); } catch {} }}
                    style={{
                      background:'var(--accent)', color:'var(--accent-ink)',
                      padding:'1px 5px', fontSize:11, fontWeight:600, cursor:'pointer',
                    }}>{part}</span>
                ) : <span key={i}>{part}</span>
              )}
            </p>
          </div>
        ))}
        {tpl.sections.length === 0 && (
          <div style={{ padding:'40px', textAlign:'center', color:'var(--ink-3)', fontSize:12, border:'1px dashed var(--rule)' }}>
            Body archived — open a current version to view full text.
          </div>
        )}
      </div>
    );
  }

  // ───── Tab: Variables
  function VariablesTab({ tpl }) {
    return (
      <div>
        <div className="ff-mono upper" style={{ fontSize:10, color:'var(--ink-3)', letterSpacing:'.12em', marginBottom:14 }}>
          {tpl.variables.length} VARIABLES · MERGE FIELDS
        </div>
        <div style={{ border:'1px solid var(--rule)' }}>
          <div className="ff-mono upper" style={{
            display:'grid', gridTemplateColumns:'40px 200px 1fr 80px 80px 1fr', gap:14,
            padding:'10px 14px', fontSize:9, color:'var(--ink-3)', background:'var(--bg-2)',
            borderBottom:'1px solid var(--rule)', letterSpacing:'.08em',
          }}>
            <span>#</span><span>TOKEN</span><span>LABEL</span><span>TYPE</span><span>REQ</span><span>EXAMPLE</span>
          </div>
          {tpl.variables.map((v,i) => (
            <div key={v.name} style={{
              display:'grid', gridTemplateColumns:'40px 200px 1fr 80px 80px 1fr', gap:14,
              padding:'12px 14px', fontSize:13, alignItems:'center',
              borderBottom: i < tpl.variables.length-1 ? '1px solid var(--rule-soft)' : 'none',
            }}>
              <span className="ff-mono num" style={{ fontSize:11, color:'var(--ink-3)' }}>{String(i+1).padStart(2,'0')}</span>
              <span className="ff-mono" style={{ fontSize:11, fontWeight:600 }}>{`{{${v.name}}}`}</span>
              <span style={{ fontSize:13 }}>{v.label}</span>
              <span><VarKindBadge kind={v.kind}/></span>
              <span className="ff-mono" style={{ fontSize:10, color: v.required ? '#c95818' : 'var(--ink-3)', fontWeight: v.required ? 600 : 400 }}>
                {v.required ? 'REQUIRED' : 'optional'}
              </span>
              <span className="ff-mono" style={{ fontSize:11, color:'var(--ink-2)' }}>
                {v.derived ? `↳ ${v.derived}` : (v.ex || '—')}
              </span>
            </div>
          ))}
          {tpl.variables.length === 0 && (
            <div style={{ padding:'30px', textAlign:'center', color:'var(--ink-3)', fontSize:12 }}>
              Variables archived for this version.
            </div>
          )}
        </div>
      </div>
    );
  }

  // ───── Tab: Versions
  function VersionsTab({ tpl }) {
    const versions = [
      { n: tpl.version, label: `v${tpl.version} · ${tpl.reviewedAt}`, notes: 'CURRENT — counsel-reviewed and live.', current:true },
      ...tpl.altVersions,
    ];
    return (
      <div>
        <div className="ff-mono upper" style={{ fontSize:10, color:'var(--ink-3)', letterSpacing:'.12em', marginBottom:14 }}>
          VERSION HISTORY
        </div>
        <div style={{ position:'relative', paddingLeft:24 }}>
          <div style={{ position:'absolute', left:7, top:6, bottom:6, width:1, background:'var(--rule)' }}/>
          {versions.map((v,i) => (
            <div key={v.n} style={{ position:'relative', paddingBottom: i < versions.length-1 ? 28 : 0, marginBottom: i < versions.length-1 ? 0 : 0 }}>
              <div style={{
                position:'absolute', left:-23, top:4, width:14, height:14, borderRadius:'50%',
                background: v.current ? 'var(--ink)' : 'var(--bg)', border:'2px solid var(--ink)',
              }}/>
              <div style={{ display:'flex', alignItems:'baseline', gap:12 }}>
                <span className="ff-mono" style={{ fontSize:13, fontWeight:600, color: v.current ? 'var(--ink)' : 'var(--ink-2)' }}>
                  {v.label}
                </span>
                {v.current && (
                  <span className="ff-mono upper" style={{ fontSize:9, padding:'2px 6px', background:'#1a4d1a', color:'#fff', letterSpacing:'.1em', fontWeight:600 }}>
                    CURRENT
                  </span>
                )}
              </div>
              <p style={{ fontSize:13, color:'var(--ink-2)', margin:'6px 0 0', lineHeight:1.55 }}>{v.notes}</p>
              {!v.current && (
                <button className="ff-mono upper" style={{
                  marginTop:8, padding:'5px 10px', fontSize:9, letterSpacing:'.08em', fontWeight:600,
                  background:'transparent', color:'var(--ink-2)', border:'1px solid var(--rule)', cursor:'pointer',
                }}>VIEW DIFF →</button>
              )}
            </div>
          ))}
        </div>
      </div>
    );
  }

  // ───── Tab: Usage — agreements spawned from this template
  function UsageTab({ tpl, go }) {
    // Derive a deterministic mock of agreements that came from this template
    const ags = (window.AGREEMENTS || []);
    const N = Math.min(tpl.usageCount, 12);
    const sample = ags.slice(0, N);

    return (
      <div>
        <div style={{ display:'grid', gridTemplateColumns:'repeat(4, 1fr)', border:'1px solid var(--rule)', marginBottom:24 }}>
          {[
            { l:'TOTAL EXECUTED', v:fmtInt(tpl.usageCount), sub:'agreements spawned from this template' },
            { l:'LAST USED',      v: tpl.lastUsed,           sub:'most recent execution' },
            { l:'AVG TIME-TO-SIGN', v: '4.2d',               sub:'sent → fully countersigned' },
            { l:'COUNTER-PARTY EDITS', v: '6%',              sub:'% of envelopes with redlines' },
          ].map((c,i) => (
            <div key={i} style={{ padding:'16px 18px', borderRight: i<3 ? '1px solid var(--rule)' : 'none' }}>
              <div className="ff-mono upper" style={{ fontSize:9, color:'var(--ink-3)', letterSpacing:'.12em', marginBottom:6 }}>{c.l}</div>
              <div className="ff-display num" style={{ fontSize:24, fontWeight:600, letterSpacing:'-0.02em' }}>{c.v}</div>
              <div className="ff-mono" style={{ fontSize:10, color:'var(--ink-3)', marginTop:4 }}>{c.sub}</div>
            </div>
          ))}
        </div>

        <div className="ff-mono upper" style={{ fontSize:10, color:'var(--ink-3)', letterSpacing:'.12em', marginBottom:14 }}>
          RECENT EXECUTED AGREEMENTS (sample)
        </div>
        <div style={{ border:'1px solid var(--rule)' }}>
          <div className="ff-mono upper" style={{
            display:'grid', gridTemplateColumns:'120px 1.4fr 1fr 100px 90px 90px', gap:14,
            padding:'10px 14px', fontSize:9, color:'var(--ink-3)', background:'var(--bg-2)',
            borderBottom:'1px solid var(--rule)', letterSpacing:'.08em',
          }}>
            <span>ID</span><span>PARTIES</span><span>TERRITORY</span><span>TERM</span><span>STATUS</span><span style={{textAlign:'right'}}>VALUE</span>
          </div>
          {sample.map((ag,i) => (
            <div key={ag.id} onClick={() => go && go('agreement', ag)} style={{
              display:'grid', gridTemplateColumns:'120px 1.4fr 1fr 100px 90px 90px', gap:14,
              padding:'12px 14px', fontSize:12, alignItems:'center', cursor:'pointer',
              borderBottom: i < sample.length-1 ? '1px solid var(--rule-soft)' : 'none',
            }}
              onMouseEnter={e=>e.currentTarget.style.background='var(--bg-2)'}
              onMouseLeave={e=>e.currentTarget.style.background='transparent'}>
              <span className="ff-mono" style={{ fontSize:11, fontWeight:600 }}>{ag.id}</span>
              <span style={{ fontSize:12 }}>
                <strong>{ag.a}</strong> <span className="ff-mono" style={{ color:'var(--ink-4)', margin:'0 4px' }}>×</span> <strong>{ag.b}</strong>
              </span>
              <span className="ff-mono" style={{ fontSize:11 }}>{ag.territory}</span>
              <span className="ff-mono" style={{ fontSize:11 }}>{ag.term}</span>
              <span className="ff-mono upper" style={{ fontSize:9, letterSpacing:'.1em', fontWeight:600,
                color: ag.status === 'active' ? '#1a4d1a' : ag.status === 'expiring' ? '#c95818' : 'var(--ink-3)' }}>
                {ag.status}
              </span>
              <span className="ff-mono num" style={{ fontSize:11, textAlign:'right', fontWeight:600 }}>{ag.value}</span>
            </div>
          ))}
          {sample.length === 0 && (
            <div style={{ padding:'30px', textAlign:'center', color:'var(--ink-3)', fontSize:12 }}>
              No agreements spawned yet.
            </div>
          )}
        </div>
        {tpl.usageCount > sample.length && (
          <div style={{ padding:'12px 0', textAlign:'center' }}>
            <span className="ff-mono" style={{ fontSize:11, color:'var(--ink-3)' }}>
              Showing {sample.length} of {fmtInt(tpl.usageCount)} executed agreements
            </span>
          </div>
        )}
      </div>
    );
  }

  // ─────────── Main screen
  function ScreenAgreementTemplates({ go, payload }) {
    const [activeId, setActiveId] = useState(payload?.id || TEMPLATES[0].id);
    const [search, setSearch]     = useState('');
    const [showInactive, setShowInactive] = useState(false);

    const groups = useMemo(() => {
      const filtered = TEMPLATES.filter(t => {
        if (!showInactive && !t.isActive) return false;
        if (search) {
          const s = search.toLowerCase();
          if (!t.name.toLowerCase().includes(s) &&
              !t.description.toLowerCase().includes(s) &&
              !t.kindLabel.toLowerCase().includes(s) &&
              !t.id.toLowerCase().includes(s)) return false;
        }
        return true;
      });
      const byCode = {};
      filtered.forEach(t => { (byCode[t.code] ||= []).push(t); });
      return KIND_ORDER.filter(c => byCode[c]).map(c => ({ code:c, label:KIND_LABELS[c]?.label || c, items:byCode[c] }));
    }, [search, showInactive]);

    const active = useMemo(() => TEMPLATES.find(t => t.id === activeId), [activeId]);

    const totalActive = TEMPLATES.filter(t => t.isActive).length;
    const totalUsages = TEMPLATES.reduce((s,t) => s + (t.isActive ? t.usageCount : 0), 0);
    const needsReview = TEMPLATES.filter(t => {
      if (!t.isActive) return false;
      const ago = (new Date('2026-04-30') - new Date(t.reviewedAt)) / (1000*60*60*24*365);
      return ago > 1;
    }).length;
    const uniqueKinds = new Set(TEMPLATES.filter(t => t.isActive).map(t => t.code)).size;

    return (
      <div>
        {/* Breadcrumb */}
        <div className="ff-mono upper" style={{ fontSize:10, color:'var(--ink-3)', letterSpacing:'.12em', marginBottom:8, display:'flex', gap:10 }}>
          <button onClick={() => go && go('catalog', { tab:'agreements' })} style={{ background:'transparent', border:0, padding:0, color:'inherit', cursor:'pointer', font:'inherit', letterSpacing:'inherit' }}>← AGREEMENTS</button>
          <span style={{ color:'var(--ink-4)' }}>/</span>
          <span>TEMPLATE LIBRARY</span>
        </div>

        {/* Title */}
        <div style={{ marginBottom:24 }}>
          <h1 className="ff-display" style={{ fontSize:48, fontWeight:600, letterSpacing:'-0.03em', margin:0, lineHeight:1 }}>
            Template library
          </h1>
          <p style={{ fontSize:14, color:'var(--ink-2)', maxWidth:680, margin:'14px 0 0', lineHeight:1.5 }}>
            The contract forms every executed agreement is spawned from. Each template has a <em>current</em> counsel-reviewed version, a body with merge tokens, a typed variable set, and a usage trail.
            Edits land as a new version; the old version remains available for in-flight deals.
          </p>
        </div>

        {/* Stats */}
        <div style={{ display:'grid', gridTemplateColumns:'repeat(4, 1fr)', border:'1px solid var(--rule)', marginBottom:24 }}>
          {[
            { l:'ACTIVE TEMPLATES', v: fmtInt(totalActive), sub:'available to spawn from' },
            { l:'KINDS COVERED',    v: uniqueKinds,         sub:'pub · rec · sync · mech · subpub · prod' },
            { l:'AGREEMENTS SPAWNED', v: fmtInt(totalUsages), sub:'lifetime' },
            { l:'NEEDS RE-REVIEW',  v: needsReview,         sub:'last reviewed >12 months ago', tone: needsReview ? 'accent' : null },
          ].map((c,i) => (
            <div key={i} style={{
              padding:'18px 20px', borderRight: i<3 ? '1px solid var(--rule)' : 'none',
              background: c.tone === 'accent' ? 'var(--accent)' : 'transparent',
              color: c.tone === 'accent' ? 'var(--accent-ink)' : 'var(--ink)',
            }}>
              <div className="ff-mono upper" style={{ fontSize:9, letterSpacing:'.12em', color: c.tone === 'accent' ? 'var(--accent-ink)' : 'var(--ink-3)', opacity: c.tone === 'accent' ? 0.7 : 1, marginBottom:6 }}>{c.l}</div>
              <div className="ff-display num" style={{ fontSize:30, fontWeight:600, letterSpacing:'-0.02em' }}>{c.v}</div>
              <div className="ff-mono" style={{ fontSize:10, color: c.tone === 'accent' ? 'var(--accent-ink)' : 'var(--ink-3)', opacity: c.tone === 'accent' ? 0.7 : 1, marginTop:4 }}>{c.sub}</div>
            </div>
          ))}
        </div>

        {/* Two-pane: list + inspector */}
        <div style={{ display:'grid', gridTemplateColumns:'380px 1fr', border:'1px solid var(--rule)', minHeight:600 }}>
          {/* List */}
          <div style={{ borderRight:'1px solid var(--rule)', display:'flex', flexDirection:'column', maxHeight:'calc(100vh - 360px)' }}>
            <div style={{ padding:'12px 14px', borderBottom:'1px solid var(--rule)', display:'flex', flexDirection:'column', gap:8 }}>
              <input value={search} onChange={e => setSearch(e.target.value)} placeholder="Search templates…"
                className="ff-mono"
                style={{ padding:'8px 10px', fontSize:11, border:'1px solid var(--rule)', background:'var(--paper)', width:'100%', boxSizing:'border-box' }}/>
              <label className="ff-mono upper" style={{ display:'flex', alignItems:'center', gap:8, fontSize:9, letterSpacing:'.1em', color:'var(--ink-3)', cursor:'pointer' }}>
                <input type="checkbox" checked={showInactive} onChange={e => setShowInactive(e.target.checked)} style={{ margin:0 }}/>
                SHOW INACTIVE / LEGACY
              </label>
            </div>
            <div style={{ overflow:'auto', flex:1 }}>
              {groups.map(g => (
                <div key={g.code}>
                  <div className="ff-mono upper" style={{
                    padding:'10px 14px', fontSize:9, color:'var(--ink-3)', letterSpacing:'.12em',
                    background:'var(--bg-2)', borderBottom:'1px solid var(--rule-soft)', borderTop:'1px solid var(--rule-soft)',
                    fontWeight:600,
                  }}>
                    {g.label} <span style={{ color:'var(--ink-4)' }}>· {g.items.length}</span>
                  </div>
                  {g.items.map(t => (
                    <button key={t.id} onClick={() => setActiveId(t.id)}
                      style={{
                        width:'100%', textAlign:'left', background: activeId===t.id ? 'var(--ink)' : 'transparent',
                        color: activeId===t.id ? 'var(--bg)' : 'var(--ink)',
                        padding:'12px 14px', border:0, borderBottom:'1px solid var(--rule-soft)',
                        cursor:'pointer', display:'block',
                      }}>
                      <div style={{ display:'flex', alignItems:'baseline', gap:8 }}>
                        <span style={{ fontSize:12.5, fontWeight:600, flex:1, minWidth:0, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
                          {t.name}
                        </span>
                        <span className="ff-mono" style={{ fontSize:10, color: activeId===t.id ? 'rgba(255,255,255,0.6)' : 'var(--ink-3)' }}>v{t.version}</span>
                      </div>
                      <div className="ff-mono" style={{ fontSize:10, marginTop:4, display:'flex', gap:8, color: activeId===t.id ? 'rgba(255,255,255,0.55)' : 'var(--ink-3)' }}>
                        <span>{fmtInt(t.usageCount)} uses</span>
                        <span>·</span>
                        <span>{t.pages}pp</span>
                        {!t.isCurrent && <><span>·</span><span style={{ color:'#c95818' }}>LEGACY</span></>}
                        {!t.isActive && <><span>·</span><span style={{ color:'#c95818' }}>INACTIVE</span></>}
                      </div>
                    </button>
                  ))}
                </div>
              ))}
              {groups.length === 0 && (
                <div style={{ padding:'40px 20px', textAlign:'center', color:'var(--ink-3)', fontSize:12 }}>
                  No templates match.
                </div>
              )}
            </div>
            <div style={{ padding:'10px 14px', borderTop:'1px solid var(--rule)', background:'var(--bg-2)' }}>
              <button className="ff-mono upper" style={{
                width:'100%', padding:'8px', fontSize:10, letterSpacing:'.1em', fontWeight:600,
                background:'transparent', color:'var(--ink)', border:'1px dashed var(--rule)', cursor:'pointer',
              }}>+ NEW TEMPLATE</button>
            </div>
          </div>

          {/* Inspector */}
          <div style={{ overflow:'auto', maxHeight:'calc(100vh - 360px)' }}>
            <Inspector tpl={active} go={go}/>
          </div>
        </div>

        {/* Footnote */}
        <div className="ff-mono" style={{ marginTop:18, fontSize:10, color:'var(--ink-3)', letterSpacing:'.04em' }}>
          Sourced from <strong>astro.agreement_templates</strong>. New version = INSERT row with version_number+1, set is_current=true on new and false on prior. Legal review tracked via reviewed_by/reviewed_at.
        </div>
      </div>
    );
  }

  // Export
  window.ScreenAgreementTemplates = ScreenAgreementTemplates;
  window.AGREEMENT_TEMPLATES = TEMPLATES;
})();
