// kova/vault.jsx — Wave E · Inventory Manager
// ----------------------------------------------------------------
// Architecture v7 §8.3 implementation. Routes:
//   /vault                  VaultOverviewPage
//   /vault/queue            VaultQueuePage (aged SKU queue, filterable)
//   /vault/items/:id        VaultItemDetailPage (SKU 360)
//   /vault/actions/:id      VaultActionDetailPage (draft → submit)
//
// IM workflow (matches §2 runtime loop + §1.5 verified outputs):
//   1. vault.deadstock_scan workflow surfaces aged SKUs with recommended actions
//   2. IM reviews items, drafts an action (hold | transfer | reprice)
//   3. Transfer needs Logistics co-sign · Reprice needs Pricing co-sign · Hold is IM-only
//   4. IM submits → moves into APPROVALS for CEO sign
//   5. CEO approves → CONNECT executes (Tally + WMS + PRICE engine)
//   6. Outcome tracked
//
// Atomic composition · pages only use Templates · new VaultItemCard composes
// only atoms/molecules · design-skill discipline preserved (no fake jewellery
// imagery, only labeled SKU monogram placeholders).
// ----------------------------------------------------------------

const {
  Btn, Chip, Kbd, Icon, Card, PageHead, KPITile, Tabs, StatusBadge, RunBadge,
  VerificationStamp, ConfidenceMeter, ApprovalChain,
  EmptyState,
  DecisionCard, RunObject, EvidencePanel, WorkflowTimeline,
  ApprovalSurface,
  ModuleOverview, DetailObject, ListTable,
  SEED_VAULT_ITEMS, SEED_VAULT_ACTIONS,
} = window.K;

const { useState, useMemo } = React;


/* ============================================================
   SKU AVATAR · placeholder · architecture v7 forbids fake jewellery imagery
   (and the design skill warns against SVG silhouettes as product shots).
   We render a labeled square with the SKU's monogram instead.
   ============================================================ */
const SKUAvatar = ({ sku, size = 44 }) => (
  <div style={{
    width: size, height: size, borderRadius: 6,
    background: 'linear-gradient(135deg, var(--surface-2), var(--line-2))',
    border: '1px solid var(--line)',
    display: 'grid', placeItems: 'center',
    fontFamily: 'var(--font-mono)',
    fontSize: size > 36 ? 11 : 9,
    color: 'var(--ink-2)',
    fontWeight: 600,
    letterSpacing: 0,
    flexShrink: 0,
  }}>
    {sku.replace(/^SKU-/, '').slice(0, 5)}
  </div>
);


/* ============================================================
   ACTION TYPE CHIP — distinct visuals for hold / transfer / reprice
   ============================================================ */
const ActionTypeChip = ({ type, small = false }) => {
  const config = {
    hold:     { variant: 'mute',    label: 'HOLD' },
    transfer: { variant: 'info',    label: 'TRANSFER' },
    reprice:  { variant: 'warn',    label: 'REPRICE' },
  }[type] || { variant: 'mute', label: type?.toUpperCase() };
  return <Chip variant={config.variant} dot={!small}>{config.label}</Chip>;
};


/* ============================================================
   VAULT ITEM CARD — compact aged-SKU row · new organism
   Composes only atoms/molecules (SKUAvatar + Chip + ActionTypeChip + Btn).
   ============================================================ */
const VaultItemCard = ({ item, onOpen, onDraftAction, selected, onSelect }) => {
  const isHigh = item.ageDays > 220;
  return (
    <div className="k-approval-row"
         style={{ '--m-mod': 'var(--m-vault)' }}>
      <div className="k-approval-stripe" />
      <div className="k-approval-body" onClick={() => onOpen?.(item.id)} style={{ cursor: 'pointer' }}>
        <div className="k-approval-head" style={{ alignItems: 'center' }}>
          {onSelect && (
            <input type="checkbox" checked={!!selected} onClick={(e) => e.stopPropagation()}
                   onChange={() => onSelect(item.id)} style={{ marginRight: 4 }} />
          )}
          <SKUAvatar sku={item.sku} />
          <div style={{ display: 'flex', flexDirection: 'column', gap: 2, minWidth: 0, flex: 1 }}>
            <div className="k-approval-title" style={{ fontSize: 15, margin: 0 }}>{item.name}</div>
            <div className="t-meta" style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
              <span className="t-mono" style={{ color: 'var(--ink-2)' }}>{item.sku}</span>
              <span>· {item.city}</span>
              <span>· aged {item.ageDays} d</span>
              <span>· {item.value.display}</span>
            </div>
          </div>
          {isHigh && <Chip variant="warn" dot>HIGH AGE</Chip>}
        </div>
        <div className="k-approval-stats" style={{ marginTop: 12 }}>
          <div className="k-approval-stat">
            <span className="l">Recommend</span>
            <span className="v"><ActionTypeChip type={item.recommendedAction.type} /></span>
          </div>
          {item.recommendedAction.toCity && (
            <div className="k-approval-stat">
              <span className="l">Destination</span>
              <span className="v">{item.recommendedAction.toCity}</span>
            </div>
          )}
          {item.recommendedAction.newPriceHint && (
            <div className="k-approval-stat">
              <span className="l">Reprice</span>
              <span className="v">{item.recommendedAction.newPriceHint}</span>
            </div>
          )}
          {item.recommendedAction.holdWindowDays && (
            <div className="k-approval-stat">
              <span className="l">Hold window</span>
              <span className="v">{item.recommendedAction.holdWindowDays} d</span>
            </div>
          )}
          <div className="k-approval-stat">
            <span className="l">Projected unlock</span>
            <span className={`v${item.recommendedAction.projectedUnlock?.amount > 0 ? ' is-success' : ''}`}>
              {item.recommendedAction.projectedUnlock?.display || '—'}
            </span>
          </div>
          <div className="k-approval-stat">
            <span className="l">Confidence</span>
            <span className="v"><ConfidenceMeter level={item.recommendedAction.confidence}
                                                  label={['Low','Med','High','Verified'][item.recommendedAction.confidence - 1]}
                                                  mod="vault" /></span>
          </div>
        </div>
      </div>
      <div className="k-approval-actions" onClick={(e) => e.stopPropagation()}>
        <Btn size="sm" variant="primary"
             onClick={() => onDraftAction?.(item.id, item.recommendedAction.type)}>
          Draft {item.recommendedAction.type}
        </Btn>
        <Btn size="sm" variant="ghost" onClick={() => onOpen?.(item.id)}>Open SKU</Btn>
      </div>
    </div>
  );
};


/* ============================================================
   VAULT OVERVIEW — IM landing page
   Template: ModuleOverview
   ============================================================ */
const VaultOverviewPage = ({
  user = 'Asha', items, actions,
  onRunScan, onOpenQueue, onOpenItem, onOpenAction, onDraftAction,
  onSubmit, onDiscard, onRefine, onExport,
  onOpenDrawer, onOpenCmdK,
}) => {
  const flagged = items.filter(i => i.status === 'recommended_action');
  const draftActions = actions.filter(a => a.status === 'pending' || a.status === 'revising');
  const primary = draftActions[0];
  const totalUnlock = flagged.reduce((s, i) => s + (i.recommendedAction.projectedUnlock?.amount || 0), 0);
  const cosignsNeeded = draftActions.filter(a => a.cosign?.includes('Pricing') || a.cosign?.includes('Logistics')).length;

  const pageHead = (
    <PageHead
      crumb={['VAULT', 'today', '09:42 IST']}
      title={`Good morning, ${user}.`}
      subtitle={flagged.length === 0
        ? 'No items flagged. Last scan ran ~6 hours ago.'
        : `${flagged.length} SKUs flagged · ${draftActions.length} action draft${draftActions.length === 1 ? '' : 's'} in flight · ${cosignsNeeded} need co-sign.`}
      actions={
        <>
          <Btn size="sm" onClick={onRunScan}>Run scan</Btn>
          <Btn size="sm" onClick={onExport} disabled={flagged.length === 0}>Export action list</Btn>
          {primary
            ? <Btn size="sm" variant="primary" onClick={() => onOpenAction?.(primary.id)} kbd="⌘⏎">
                Open next draft
              </Btn>
            : <Btn size="sm" variant="primary" onClick={onOpenQueue}>Open queue</Btn>}
        </>
      }
    />
  );

  const kpis = [
    <KPITile key="a" mod="vault" label="Items aged > 180 d" value={String(flagged.length)}
             foot={flagged.length ? `${flagged.length === 1 ? '1 SKU' : `${flagged.length} SKUs`} across 4 cities` : 'inbox zero'} />,
    <KPITile key="b" mod="vault" label="Unlock identified"
             value={`₹${(totalUnlock / 100000).toFixed(1)} L`}
             valueColor="var(--success)"
             foot="across all flagged items" />,
    <KPITile key="c" mod="approvals" label="Actions in flight"
             value={String(draftActions.length)}
             foot={cosignsNeeded ? `${cosignsNeeded} need co-sign` : 'no co-sign blockers'} />,
    <KPITile key="d" mod="connect" label="Scan health"
             value="green"
             valueColor="var(--success)"
             foot="last run · 6 h ago" />,
  ];

  const empty = (
    <Card>
      <EmptyState
        mark="V"
        title="No aged items in scope."
        body="Vault scans every 6 hours. Next scan in ~2 h, or run one now."
        cta={<Btn size="sm" variant="primary" onClick={onRunScan}>Run scan now</Btn>}
      />
    </Card>
  );

  const primaryNode = primary && (
    <DecisionCard
      {...primary}
      stamp={primary.stamp}
      onEvidence={() => onOpenDrawer?.(primary.id)}
      onRunHistory={() => location.hash = `monitor/${primary.runId}`}
      onReject={() => onDiscard?.(primary.id)}
      onRevise={() => onRefine?.(primary.id)}
      onApprove={() => onSubmit?.(primary.id)}
      primaryKbd="⌘⏎"
    />
  );

  /* Aged-by-city breakdown */
  const byCity = useMemo(() => {
    const acc = {};
    flagged.forEach(i => {
      acc[i.city] = acc[i.city] || { count: 0, value: 0 };
      acc[i.city].count += 1;
      acc[i.city].value += i.value.amount;
    });
    return Object.entries(acc).sort((a, b) => b[1].value - a[1].value);
  }, [flagged]);

  const queueTeaser = flagged.length > 0 && (
    <Card>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
        <div className="t-eyebrow">Top recommendations · {Math.min(3, flagged.length)} of {flagged.length}</div>
        <Btn size="sm" variant="ghost" onClick={onOpenQueue}>Open queue ›</Btn>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
        {flagged.slice(0, 3).map(item => (
          <VaultItemCard key={item.id} item={item}
                         onOpen={onOpenItem}
                         onDraftAction={onDraftAction} />
        ))}
      </div>
    </Card>
  );

  const side = [
    <Card key="cities">
      <div className="t-eyebrow" style={{ marginBottom: 10 }}>Aged inventory · by city</div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {byCity.map(([city, agg]) => (
          <div key={city} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', fontSize: 13 }}>
            <span className="t-meta">{city}</span>
            <span>
              <span className="t-mono" style={{ color: 'var(--ink)' }}>{agg.count}</span>
              <span className="t-meta" style={{ marginLeft: 8 }}>₹{(agg.value / 100000).toFixed(1)} L</span>
            </span>
          </div>
        ))}
      </div>
    </Card>,
    <Card key="quick">
      <div className="t-eyebrow" style={{ marginBottom: 10 }}>Quick actions</div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
        <Btn size="sm" variant="ghost" onClick={onRunScan}>Run deadstock scan</Btn>
        <Btn size="sm" variant="ghost" onClick={onOpenQueue}>Open full queue</Btn>
        <Btn size="sm" variant="ghost" onClick={onExport}>Export action list (CSV)</Btn>
        <Btn size="sm" variant="ghost" onClick={onOpenCmdK} kbd="⌘ K">Jump to…</Btn>
      </div>
    </Card>,
    <Card key="actions">
      <div className="t-eyebrow" style={{ marginBottom: 10 }}>Other drafts · {Math.max(0, draftActions.length - 1)}</div>
      {draftActions.slice(1).map(a => (
        <div key={a.id} style={{ padding: '10px 0', borderTop: '1px solid var(--line-2)', cursor: 'pointer' }}
             onClick={() => onOpenAction?.(a.id)}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}>
            <ActionTypeChip type={a.type} small />
            <span className="t-mono" style={{ fontSize: 11, color: 'var(--mute)' }}>{a.runId}</span>
          </div>
          <div style={{ fontSize: 12.5, color: 'var(--ink)', lineHeight: 1.4 }}>{a.title}</div>
        </div>
      ))}
      {draftActions.length <= 1 && <div className="t-meta">No other drafts.</div>}
    </Card>,
  ];

  return (
    <ModuleOverview
      pageHead={pageHead}
      kpis={kpis}
      primary={primaryNode}
      secondary={queueTeaser}
      side={side}
      empty={flagged.length === 0 ? empty : null}
    />
  );
};


/* ============================================================
   VAULT QUEUE PAGE — filterable list of aged SKUs
   Template: ListTable
   ============================================================ */
const VaultQueuePage = ({ items, onOpenItem, onDraftAction, onRunScan, onExport, onOpenCmdK }) => {
  const [actionFilter, setActionFilter] = useState('all');
  const [cityFilter, setCityFilter] = useState('all');
  const [selected, setSelected] = useState(new Set());

  const filtered = useMemo(() => {
    let xs = items.filter(i => i.status === 'recommended_action');
    if (actionFilter !== 'all') xs = xs.filter(i => i.recommendedAction.type === actionFilter);
    if (cityFilter !== 'all')   xs = xs.filter(i => i.city === cityFilter);
    return xs;
  }, [items, actionFilter, cityFilter]);

  const counts = {
    all:      items.filter(i => i.status === 'recommended_action').length,
    hold:     items.filter(i => i.recommendedAction.type === 'hold').length,
    transfer: items.filter(i => i.recommendedAction.type === 'transfer').length,
    reprice:  items.filter(i => i.recommendedAction.type === 'reprice').length,
  };
  const cities = [...new Set(items.map(i => i.city))];

  const toggleSelect = (id) => {
    setSelected(prev => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id); else next.add(id);
      return next;
    });
  };

  return (
    <ListTable
      pageHead={
        <PageHead
          crumb={['VAULT', 'queue']}
          title="Aged inventory queue"
          subtitle="Items flagged by the last deadstock scan. Filter by action or city; draft any item, or export the full list to CSV."
          actions={
            <>
              <Btn size="sm" onClick={onOpenCmdK} kbd="⌘K">Jump to…</Btn>
              <Btn size="sm" onClick={onExport}
                   disabled={selected.size === 0 && filtered.length === 0}>
                {selected.size > 0 ? `Export ${selected.size} selected` : 'Export action list'}
              </Btn>
              <Btn size="sm" variant="primary" onClick={onRunScan}>Run scan</Btn>
            </>
          }
        />
      }
      tabs={
        <Tabs value={actionFilter} onChange={setActionFilter} mod="vault" items={[
          { id: 'all',      label: 'All',      count: counts.all },
          { id: 'transfer', label: 'Transfer', count: counts.transfer },
          { id: 'reprice',  label: 'Reprice',  count: counts.reprice },
          { id: 'hold',     label: 'Hold',     count: counts.hold },
        ]} />
      }
      filterBar={
        <div className="k-inbox-filter">
          <span className="k-inbox-filter-label">City</span>
          <div className="k-inbox-filter-chips">
            <Chip variant={cityFilter === 'all' ? 'solid' : 'mute'} onClick={() => setCityFilter('all')}>All</Chip>
            {cities.map(c => (
              <Chip key={c} variant={cityFilter === c ? 'solid' : 'mute'} onClick={() => setCityFilter(c)}>{c}</Chip>
            ))}
          </div>
        </div>
      }
      empty={filtered.length === 0 ? (
        <Card>
          <EmptyState
            mark="V"
            title="No items match these filters."
            body="Try clearing filters or running a fresh scan."
            cta={<Btn size="sm" variant="primary" onClick={onRunScan}>Run scan now</Btn>}
          />
        </Card>
      ) : null}
      body={
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          {filtered.map(item => (
            <VaultItemCard key={item.id} item={item}
                           selected={selected.has(item.id)}
                           onSelect={toggleSelect}
                           onOpen={onOpenItem}
                           onDraftAction={onDraftAction} />
          ))}
        </div>
      }
    />
  );
};


/* ============================================================
   VAULT ITEM DETAIL — SKU 360 view
   Template: DetailObject
   ============================================================ */
const VaultItemDetailPage = ({
  item, onBack, onDraftAction, onAssignOwner, onCreateKraftRemake, onOpenSignals,
}) => {
  if (!item) {
    return (
      <DetailObject
        back={<button className="k-detail-back" onClick={onBack}>← Back to queue</button>}
        pageHead={<PageHead crumb={['VAULT', 'items']} title="SKU not found" />}
        main={[
          <Card key="x">
            <EmptyState mark="?"
              title="That SKU doesn't exist."
              body="It may have been sold, transferred out, or melted."
              cta={<Btn size="sm" onClick={onBack}>Back to queue</Btn>} />
          </Card>
        ]}
        side={[]}
      />
    );
  }

  const rec = item.recommendedAction;

  return (
    <DetailObject
      back={<button className="k-detail-back" onClick={onBack}>← Back to queue</button>}
      pageHead={
        <PageHead
          crumb={['VAULT', 'items', item.sku]}
          title={item.name}
          subtitle={`${item.cohort} · ${item.city} · aged ${item.ageDays} d · ${item.value.display}`}
          actions={
            <>
              <Btn size="sm" onClick={() => onAssignOwner?.(item.id)}>Assign owner</Btn>
              <Btn size="sm" onClick={() => onCreateKraftRemake?.(item.id)}>Create KRAFT remake brief</Btn>
              <Btn size="sm" variant="primary"
                   onClick={() => onDraftAction?.(item.id, rec.type)} kbd="⌘⏎">
                Draft {rec.type}
              </Btn>
            </>
          }
        />
      }
      statusRow={
        <>
          <VerificationStamp>Verified · vault.deadstock_scan</VerificationStamp>
          <ActionTypeChip type={rec.type} />
          <ConfidenceMeter level={rec.confidence} label={['Low','Medium','High','Verified'][rec.confidence - 1]} mod="vault" />
          <Chip variant="warn" dot>Aged {item.ageDays} d</Chip>
          {item.ageDays > 220 && <Chip variant="danger" dot>HIGH AGE</Chip>}
        </>
      }
      main={[
        <Card key="hero">
          <div style={{ display: 'flex', gap: 16, alignItems: 'flex-start' }}>
            <SKUAvatar sku={item.sku} size={80} />
            <div style={{ flex: 1, minWidth: 0 }}>
              <div className="t-eyebrow" style={{ marginBottom: 4 }}>SKU · 360</div>
              <div className="t-h2" style={{ marginBottom: 8 }}>{item.name}</div>
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 16 }}>
                <div><div className="t-eyebrow" style={{ color: 'var(--mute)' }}>SKU code</div><div className="t-mono" style={{ color: 'var(--ink)', marginTop: 2 }}>{item.sku}</div></div>
                <div><div className="t-eyebrow" style={{ color: 'var(--mute)' }}>City</div><div style={{ color: 'var(--ink)', marginTop: 2 }}>{item.city}</div></div>
                <div><div className="t-eyebrow" style={{ color: 'var(--mute)' }}>Cohort</div><div style={{ color: 'var(--ink)', marginTop: 2 }}>{item.cohort}</div></div>
                <div><div className="t-eyebrow" style={{ color: 'var(--mute)' }}>Listed value</div><div style={{ color: 'var(--ink)', marginTop: 2, fontWeight: 600, fontVariantNumeric: 'tabular-nums' }}>{item.value.display}</div></div>
              </div>
            </div>
          </div>
        </Card>,
        <Card key="rec">
          <div className="t-eyebrow" style={{ marginBottom: 12 }}>Recommended action · agent</div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 14 }}>
            <ActionTypeChip type={rec.type} />
            {rec.toCity && <span style={{ fontSize: 14, color: 'var(--ink)' }}>{item.city} → <strong>{rec.toCity}</strong></span>}
            {rec.newPriceHint && <span style={{ fontSize: 14, color: 'var(--ink)' }}>{rec.newPriceHint}</span>}
            {rec.holdWindowDays && <span style={{ fontSize: 14, color: 'var(--ink)' }}>for {rec.holdWindowDays} days</span>}
          </div>
          <p className="t-body" style={{ color: 'var(--ink-2)', lineHeight: 1.55, margin: 0 }}>
            {rec.rationale}
          </p>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                        marginTop: 16, paddingTop: 12, borderTop: '1px solid var(--line-2)' }}>
            <div style={{ display: 'flex', gap: 24 }}>
              <div>
                <div className="t-eyebrow" style={{ color: 'var(--mute)' }}>Projected unlock</div>
                <div style={{ fontSize: 18, fontWeight: 600, color: 'var(--success)',
                              fontVariantNumeric: 'tabular-nums', marginTop: 2 }}>
                  {rec.projectedUnlock?.display || '—'}
                </div>
              </div>
              <div>
                <div className="t-eyebrow" style={{ color: 'var(--mute)' }}>Confidence</div>
                <div style={{ marginTop: 2 }}>
                  <ConfidenceMeter level={rec.confidence}
                                   label={['Low','Medium','High','Verified'][rec.confidence - 1]}
                                   mod="vault" />
                </div>
              </div>
            </div>
            <Btn variant="primary" onClick={() => onDraftAction?.(item.id, rec.type)} kbd="⌘⏎">
              Draft {rec.type}
            </Btn>
          </div>
        </Card>,
        <Card key="signals">
          <div className="t-eyebrow" style={{ marginBottom: 10 }}>Source signals · {item.signals.length}</div>
          {item.signals.length === 0 ? (
            <div className="t-meta">No signal-driven evidence. Recommendation derived from aging + cohort math.</div>
          ) : (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {item.signals.map(sigId => (
                <div key={sigId} style={{ display: 'flex', justifyContent: 'space-between',
                                          padding: '8px 0', borderTop: '1px solid var(--line-2)' }}>
                  <span className="t-mono" style={{ color: 'var(--accent)' }}>{sigId}</span>
                  <Btn size="sm" variant="ghost" onClick={() => onOpenSignals?.(sigId)}>Open in ORBIT ›</Btn>
                </div>
              ))}
            </div>
          )}
        </Card>,
        <Card key="timeline">
          <div className="t-eyebrow" style={{ marginBottom: 12 }}>SKU timeline · last 4 events</div>
          {[
            { when: 'Today 09:34',  meta: 'vault.deadstock_scan',  what: `Flagged · recommended ${rec.type.toUpperCase()}` },
            { when: '2 d ago',      meta: 'price.read',             what: 'Margin recomputed · still above floor' },
            { when: '14 d ago',     meta: 'sales.read',             what: `${item.city} cohort velocity ${item.ageDays > 220 ? 'down 18 %' : 'flat'}` },
            { when: `${item.ageDays} d ago`, meta: 'inventory.read', what: 'Stocked at this location' },
          ].map((e, i) => (
            <div key={i} style={{ display: 'flex', justifyContent: 'space-between',
                                  padding: '10px 0', borderTop: i ? '1px solid var(--line-2)' : 'none' }}>
              <div>
                <div style={{ fontSize: 13, color: 'var(--ink)' }}>{e.what}</div>
                <div className="t-mono" style={{ fontSize: 11, color: 'var(--mute)', marginTop: 2 }}>{e.meta}</div>
              </div>
              <span className="t-meta">{e.when}</span>
            </div>
          ))}
        </Card>,
      ]}
      side={[
        <Card key="actions">
          <div className="t-eyebrow" style={{ marginBottom: 10 }}>Draft an action</div>
          <p className="t-body-sm" style={{ color: 'var(--mute)', marginTop: 0 }}>
            Three action types per architecture §8.3. Hold is IM-only; transfer needs Logistics co-sign; reprice needs Pricing co-sign.
          </p>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginTop: 12 }}>
            <Btn variant={rec.type === 'transfer' ? 'primary' : 'default'}
                 onClick={() => onDraftAction?.(item.id, 'transfer')}>Draft transfer</Btn>
            <Btn variant={rec.type === 'reprice' ? 'primary' : 'default'}
                 onClick={() => onDraftAction?.(item.id, 'reprice')}>Draft reprice</Btn>
            <Btn variant={rec.type === 'hold' ? 'primary' : 'default'}
                 onClick={() => onDraftAction?.(item.id, 'hold')}>Draft hold</Btn>
          </div>
        </Card>,
        <Card key="cross">
          <div className="t-eyebrow" style={{ marginBottom: 10 }}>Cross-module</div>
          <p className="t-body-sm" style={{ color: 'var(--mute)', marginTop: 0 }}>
            If this SKU has reached end-of-life, route it to KRAFT for a remake brief.
          </p>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6, marginTop: 10 }}>
            <Btn size="sm" onClick={() => onCreateKraftRemake?.(item.id)}>Create KRAFT remake brief</Btn>
            <Btn size="sm" variant="ghost" onClick={() => onAssignOwner?.(item.id)}>Assign owner</Btn>
          </div>
        </Card>,
        <Card key="meta">
          <div className="t-eyebrow" style={{ marginBottom: 10 }}>Metadata</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8, fontSize: 13 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between' }}>
              <span className="t-meta">Status</span>
              <span style={{ color: 'var(--ink)' }}>{item.status.replace(/_/g, ' ')}</span>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between' }}>
              <span className="t-meta">Cohort</span>
              <span style={{ color: 'var(--ink)' }}>{item.cohort}</span>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between' }}>
              <span className="t-meta">Age</span>
              <span className="t-mono" style={{ color: 'var(--ink)' }}>{item.ageDays} d</span>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between' }}>
              <span className="t-meta">Listed value</span>
              <span className="t-mono" style={{ color: 'var(--ink)' }}>{item.value.display}</span>
            </div>
          </div>
        </Card>,
      ]}
    />
  );
};


/* ============================================================
   VAULT ACTION DETAIL — draft an action for submission
   Template: DetailObject (mirrors HoM brief detail)
   ============================================================ */
const VaultActionDetailPage = ({
  action, items, onBack, onSubmit, onRefine, onDiscard, onCosignPricing, onCosignLogistics,
}) => {
  if (!action) {
    return (
      <DetailObject
        back={<button className="k-detail-back" onClick={onBack}>← Back to VAULT</button>}
        pageHead={<PageHead crumb={['VAULT', 'actions']} title="Action not found" />}
        main={[
          <Card key="x">
            <EmptyState mark="?"
              title="That action draft doesn't exist."
              body="It may have been submitted, discarded, or expired."
              cta={<Btn size="sm" onClick={onBack}>Back to VAULT</Btn>} />
          </Card>
        ]}
        side={[]}
      />
    );
  }

  const actionItems = (action.itemIds || []).map(id => items.find(i => i.id === id)).filter(Boolean);
  const needsPricingCosign   = action.cosign?.includes('Pricing');
  const needsLogisticsCosign = action.cosign?.includes('Logistics');

  return (
    <DetailObject
      back={<button className="k-detail-back" onClick={onBack}>← Back to VAULT</button>}
      pageHead={
        <PageHead
          crumb={['VAULT', 'actions', action.runId]}
          title={action.title}
          subtitle={action.reasoning}
          actions={
            <>
              <Btn size="sm" variant="reject" onClick={() => onDiscard?.(action.id)}>Discard</Btn>
              <Btn size="sm" onClick={() => onRefine?.(action.id)}>Refine</Btn>
              {needsPricingCosign && (
                <Btn size="sm" onClick={() => onCosignPricing?.(action.id)}>Request Pricing co-sign</Btn>
              )}
              {needsLogisticsCosign && (
                <Btn size="sm" onClick={() => onCosignLogistics?.(action.id)}>Request Logistics co-sign</Btn>
              )}
              <Btn size="sm" variant="primary" onClick={() => onSubmit?.(action.id)} kbd="⌘⏎">
                Submit {action.type === 'hold' ? 'hold' : `to ${needsPricingCosign ? 'Pricing' : needsLogisticsCosign ? 'Logistics' : 'CEO'}`}
              </Btn>
            </>
          }
        />
      }
      statusRow={
        <>
          <VerificationStamp>{action.stamp || 'Verified'}</VerificationStamp>
          <ActionTypeChip type={action.type} />
          <StatusBadge kind="pending">{action.statusLabel}</StatusBadge>
          <RunBadge id={action.runId} version={action.runVersion} when={action.runWhen} />
          {action.confidence && <ConfidenceMeter level={action.confidence} label={action.confidenceLabel} mod="vault" />}
          <Chip variant="info" dot>IM drafting</Chip>
        </>
      }
      main={[
        <Card key="stats">
          <div className="t-eyebrow" style={{ marginBottom: 12 }}>Action summary</div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 16 }}>
            {action.stats.map((s, i) => (
              <div key={i} style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
                <span className="t-eyebrow" style={{ color: 'var(--mute)' }}>{s.label}</span>
                <span style={{ fontSize: 22, fontWeight: 600,
                              color: s.color === 'success' ? 'var(--success)'
                                   : s.color === 'danger'  ? 'var(--danger)' : 'var(--ink)',
                              fontVariantNumeric: 'tabular-nums', letterSpacing: '-0.01em' }}>{s.value}</span>
              </div>
            ))}
          </div>
        </Card>,
        <Card key="items">
          <div className="t-eyebrow" style={{ marginBottom: 12 }}>Items in this action · {actionItems.length}</div>
          {actionItems.length === 0 ? (
            <div className="t-meta">No items linked yet.</div>
          ) : (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {actionItems.map(item => (
                <div key={item.id} style={{ display: 'flex', gap: 12, alignItems: 'center',
                                            padding: '10px 0', borderTop: '1px solid var(--line-2)' }}>
                  <SKUAvatar sku={item.sku} size={36} />
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13, color: 'var(--ink)', fontWeight: 500 }}>{item.name}</div>
                    <div className="t-meta" style={{ display: 'flex', gap: 10, flexWrap: 'wrap', marginTop: 2 }}>
                      <span className="t-mono" style={{ color: 'var(--ink-2)' }}>{item.sku}</span>
                      <span>· {item.city}</span>
                      <span>· {item.ageDays} d</span>
                      <span>· {item.value.display}</span>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          )}
        </Card>,
        <RunObject key="run"
          mod="vault"
          runId={action.runId}
          status="pending"
          title={`vault.${action.type}_action · ${action.runVersion}`}
          agent="vault_action_agent · v2.1"
          skillVersion="acme.vault.skills @ 2026.05.18-3"
          memoryVersion="acme.memory @ 2026.05.20"
          startedAt={action.runWhen}
          cost="$0.012"
          latency="5.2 s"
          onOpenTrace={() => location.hash = `monitor/${action.runId}`}
        />,
        <WorkflowTimeline key="wf"
          title="Workflow · pre-submission"
          actions={<Btn size="sm" variant="ghost" onClick={() => location.hash = `monitor/${action.runId}`}>Open in MONITOR ›</Btn>}
          steps={action.workflow}
        />,
      ]}
      side={[
        <EvidencePanel key="ev"
          runId={action.runId}
          claims={action.claims || []}
          receipts={action.receipts || []}
          math={action.math || []}
        />,
        <ApprovalSurface key="as"
          mod="vault"
          runId={action.runId}
          title="Pre-approval chain"
          chain={action.chain}
          onReject={() => onDiscard?.(action.id)}
          onRevise={() => onRefine?.(action.id)}
          onApprove={() => onSubmit?.(action.id)}
          primaryKbd="⌘⏎"
        />,
        <Card key="impact">
          <div className="t-eyebrow" style={{ marginBottom: 10 }}>Impact preview</div>
          {action.stats.slice(0, 4).map((s, i) => (
            <div key={i} className="k-impact-row">
              <span className="l">{s.label}</span>
              <span className="v" style={{
                color: s.color === 'success' ? 'var(--success)' :
                       s.color === 'danger'  ? 'var(--danger)'  : undefined
              }}>{s.value}</span>
            </div>
          ))}
          <div className="k-impact-row">
            <span className="l">External writes</span>
            <span className="v">{action.type === 'hold' ? 'IM-only · none' : 'on CEO approval'}</span>
          </div>
        </Card>,
      ]}
      footer={
        <div className="k-detail-footer">
          <div className="k-detail-footer-left">
            <Icon name="check" />
            <span>
              {action.type === 'hold'
                ? 'Hold is IM-only · no CEO sign needed · audited.'
                : `Submitting moves this action to ${needsPricingCosign ? 'Pricing co-sign' : needsLogisticsCosign ? 'Logistics co-sign' : 'CEO approval'} · audited.`}
            </span>
          </div>
          <div className="k-detail-footer-right">
            <Btn variant="reject" onClick={() => onDiscard?.(action.id)}>Discard</Btn>
            <Btn onClick={() => onRefine?.(action.id)}>Refine</Btn>
            <Btn variant="primary" onClick={() => onSubmit?.(action.id)} kbd="⌘⏎">
              Submit {action.type === 'hold' ? 'hold' : action.type}
            </Btn>
          </div>
        </div>
      }
    />
  );
};


Object.assign(window.K, {
  VaultOverviewPage, VaultQueuePage, VaultItemDetailPage, VaultActionDetailPage,
  VaultItemCard, SKUAvatar, ActionTypeChip,
});
